Class: Opal::Rewriters::ThrowerFinder
- Inherits:
-
Base
- Object
- Parser::AST::Processor
- Base
- Opal::Rewriters::ThrowerFinder
show all
- Defined in:
- opal/lib/opal/rewriters/thrower_finder.rb
Overview
ThrowerFinder attempts to track the presence of throwers, like
break, redo, so we can make an informed guess in the early
compilation phase before traversing other nodes whether we
want to track a closure. Tracking a closure is often a deoptimizing
step, so we want to get that knowledge earlier.
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
Constructor Details
Returns a new instance of ThrowerFinder.
12
13
14
15
16
17
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 12
def initialize
@break_stack = []
@redo_stack = []
@retry_stack = []
@rescue_else_stack = []
end
|
Instance Method Details
#on_break(node) ⇒ Object
19
20
21
22
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 19
def on_break(node)
tracking(:break, @break_stack)
super
end
|
#on_defined(node) ⇒ Object
ignore throwers inside defined
49
50
51
52
53
54
55
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 49
def on_defined(node)
pushing(
[@redo_stack, nil],
[@break_stack, nil],
[@retry_stack, nil]
) { super }
end
|
#on_ensure(node) ⇒ Object
In Opal we handle rescue-else either in ensure or in
rescue. If ensure is present, we handle it in ensure.
Otherwise we handle it in rescue. ensure is always
above a rescue. This logic is about tracking if a given
ensure node should expect a rescue-else inside a
rescue node.
63
64
65
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 63
def on_ensure(node)
pushing([@rescue_else_stack, node]) { super }
end
|
#on_for(node) ⇒ Object
42
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 42
def on_for(node); on_loop(node) { super }; end
|
#on_iter(node) ⇒ Object
34
35
36
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 34
def on_iter(node)
pushing([@break_stack, node]) { super }
end
|
#on_loop(node, &block) ⇒ Object
38
39
40
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 38
def on_loop(node, &block)
pushing([@redo_stack, node], [@break_stack, nil], &block)
end
|
#on_redo(node) ⇒ Object
24
25
26
27
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 24
def on_redo(node)
tracking(:redo, @redo_stack)
super
end
|
#on_rescue(node) ⇒ Object
67
68
69
70
71
72
73
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 67
def on_rescue(node)
if node.children[1..-1].detect { |sexp| sexp && sexp.type != :resbody }
tracking(:rescue_else, @rescue_else_stack)
end
pushing([@rescue_else_stack, nil], [@retry_stack, node]) { super }
end
|
#on_retry(node) ⇒ Object
29
30
31
32
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 29
def on_retry(node)
tracking(:retry, @retry_stack)
super
end
|
#on_until(node) ⇒ Object
45
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 45
def on_until(node); on_loop(node) { super }; end
|
#on_until_post(node) ⇒ Object
46
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 46
def on_until_post(node); on_loop(node) { super }; end
|
#on_while(node) ⇒ Object
43
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 43
def on_while(node); on_loop(node) { super }; end
|
#on_while_post(node) ⇒ Object
44
|
# File 'opal/lib/opal/rewriters/thrower_finder.rb', line 44
def on_while_post(node); on_loop(node) { super }; end
|