Class: Opal::Rewriters::ThrowerFinder
- 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
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#initialize ⇒ ThrowerFinder
constructor
A new instance of ThrowerFinder.
- #on_break(node) ⇒ Object
-
#on_defined(node) ⇒ Object
ignore throwers inside defined.
-
#on_ensure(node) ⇒ Object
In Opal we handle rescue-else either in ensure or in rescue.
- #on_for(node) ⇒ Object
- #on_iter(node) ⇒ Object
- #on_loop(node, &block) ⇒ Object
- #on_redo(node) ⇒ Object
- #on_rescue(node) ⇒ Object
- #on_retry(node) ⇒ Object
- #on_until(node) ⇒ Object
- #on_until_post(node) ⇒ Object
- #on_while(node) ⇒ Object
- #on_while_post(node) ⇒ Object
Methods inherited from Base
#append_to_body , #begin_with_stmts , #dynamic! , #error , #on_top , #prepend_to_body , #process , s , #s , #stmts_of
Constructor Details
#initialize ⇒ ThrowerFinder
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