[フレーム]

Class: Opal::Rewriters::TargetedPatches

Inherits:
Base
  • Object
  • Parser::AST::Processor
  • Base
  • Opal::Rewriters::TargetedPatches
show all
Defined in:
opal/lib/opal/rewriters/targeted_patches.rb

Overview

This module attempts to run some optimizations or compatibility improvements against some libraries used with Opal.

This should be a last resort and must not break functionality in existing applications.

Constant Summary

Constants inherited from Base

Base::DUMMY_LOCATION

Instance Attribute Summary

Attributes inherited from Base

#current_node

Instance Method Summary collapse

Methods inherited from Base

#append_to_body , #begin_with_stmts , #dynamic! , #error , #on_top , #prepend_to_body , #process , s , #s , #stmts_of

Instance Method Details

#on_array(node) ⇒ Object

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'opal/lib/opal/rewriters/targeted_patches.rb', line 49
def on_array(node)
 children = node.children
 # Optimize large arrays produced by lexer, but mainly we are interested
 # in improving compile times, by reducing the tree for the further
 # compilation efforts (also reducing the bundle size a bit)
 #
 # This particular patch reduces compile time of the following command
 # by 12.5%:
 #
 # OPAL_CACHE_DISABLE=true OPAL_PREFORK_DISABLE=true bin/opal \
 # --no-source-map -ropal-parser -ropal/platform -ce \
 # 'puts ::Opal.compile($stdin.read)' > _Cnow.js
 #
 # So, in short, an array of a kind:
 #
 # [1, 2, 3, nil, nil, :something, :abc, nil, ...]
 #
 # Becomes compiled to:
 #
 # Opal.large_array_unpack("1,2,3,,something,abc,,...")

 if children.length > 32
 ssin_array = children.all? do |child|
 # Break for wrong types
 next false unless %i[strsymintnil].include?(child.type)
 # Break for strings that may conflict with our numbers, nils and separator
 next false if %i[strsym].include?(child.type) && child.children.first.to_s =~ /\A[0-9-]|\A\z|,/
 # Break for too numbers out of range, as there may be decoding issues
 next false if child.type == :int && !(-1_000_000..1_000_000).cover?(child.children.first)
 true
 end
 if ssin_array
 str = children.map { |i| i.children.first.to_s }.join(',')
 node.updated(:jscall, [s(:js_tmp, :Opal), :large_array_unpack, s(:sym, str)])
 else
 super
 end
 else
 super
 end
end

#on_def(node) ⇒ Object

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'opal/lib/opal/rewriters/targeted_patches.rb', line 13
def on_def(node)
 name, args, body = *node
 if body && body.type == :begin && body.children.length >= 2
 # parser/rubyxx.rb - racc generated code often looks like:
 #
 # def _reduce_219(val, _values, result)
 # result = @builder.op_assign(val[0], val[1], val[2])
 # result
 # end
 #
 # This converter transform this into just
 #
 # def _reduce_219(val, _values, result)
 # @builder.op_assign(val[0], val[1], val[2])
 # end

 calls = body.children
 assignment, ret = calls.last(2)
 if assignment.type == :lvasgn && ret.type == :lvar &&
 assignment.children.first == ret.children.first
 if calls.length == 2
 node.updated(nil, [name, args, assignment.children[1]])
 else
 calls = calls[0..-3] << assignment.children[1]
 node.updated(nil, [name, args, body.updated(nil, calls)])
 end
 else
 super
 end
 else
 super
 end
end

AltStyle によって変換されたページ (->オリジナル) /