class CodeTools::AST::Ensure
Attributes
body[RW]
ensure[RW]
Public Class Methods
new(line, body, ensr)
click to toggle source
# File lib/rubinius/code/ast/exceptions.rb, line 31 def initialize(line, body, ensr) @line = line @body = body || NilLiteral.new(line) @ensure = ensr end
Public Instance Methods
bytecode(g)
click to toggle source
# File lib/rubinius/code/ast/exceptions.rb, line 37 def bytecode(g) pos(g) ok = g.new_label ex = g.new_label g.setup_unwind ex, EnsureType # TODO: ? g.new_label.set! g.push_exception_state outer_exc_state = g.new_stack_local g.set_stack_local outer_exc_state g.pop old_break = g.break new_break = g.new_label g.break = new_break old_next = g.next new_next = g.new_label g.next = new_next g.state.push_ensure @body.bytecode(g) g.state.pop_ensure g.break = old_break g.next = old_next g.pop_unwind g.goto ok check_break = nil if new_break.used? used_break_local = g.new_stack_local check_break = g.new_label new_break.set! g.pop_unwind g.push_true g.set_stack_local used_break_local g.pop g.goto check_break end check_next = nil if new_next.used? used_next_local = g.new_stack_local check_next = g.new_label new_next.set! g.pop_unwind g.push_true g.set_stack_local used_next_local g.pop g.goto check_next end ex.set! g.push_exception_state g.state.push_inside_ensure g.state.push_rescue(outer_exc_state) @ensure.bytecode(g) g.state.pop_rescue g.pop g.restore_exception_state # Re-raise the exception g.reraise # There is no mapping to the original source here, so # reflect that in the lines table to try and make it # more accurate. g.set_line 0 ok.set! if check_break g.push_false g.set_stack_local used_break_local g.pop check_break.set! end if check_next g.push_false g.set_stack_local used_next_local g.pop check_next.set! end # Now, re-emit the code for the ensure which will run if there was no # exception generated. @ensure.bytecode(g) g.pop if check_break post = g.new_label g.push_stack_local used_break_local g.goto_if_false post if g.break g.goto g.break else g.raise_break end post.set! end if check_next post = g.new_label g.push_stack_local used_next_local g.goto_if_false post g.next ? g.goto(g.next) : g.ret post.set! end g.state.pop_inside_ensure end
to_sexp()
click to toggle source
# File lib/rubinius/code/ast/exceptions.rb, line 171 def to_sexp [:ensure, @body.to_sexp, @ensure.to_sexp] end