Commit 8cb40fcd authored by Kouhei Sutou's avatar Kouhei Sutou

Fix ensure with yield context on break and return

How to reproduce:

    class A
      def x
        yield
      ensure
        y
      end

      def y
      end
    end

    # Work
    A.new.x do
    end

    # Not work
    # trace:
    # 	[2] /tmp/a.rb:5:in A.x
    # 	[0] /tmp/a.rb:15
    # /tmp/a.rb:5: undefined method 'y' for main (NoMethodError)
    A.new.x do
      break
    end

    # trace:
    # 	[2] /tmp/a.rb:5:in A.call
    # 	[0] /tmp/a.rb:19
    # /tmp/a.rb:5: undefined method 'y' for main (NoMethodError)
    lambda do
      A.new.x do
        return
      end
    end.call

`self` in ensure is broken when yield and break/return are used.
parent 4957c852
......@@ -1514,6 +1514,7 @@ RETRY_TRY_BLOCK:
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
goto L_RAISE;
}
mrb->c->stack = mrb->c->ci->stackent;
mrb->c->ci = ci;
break;
}
......@@ -1548,6 +1549,7 @@ RETRY_TRY_BLOCK:
c->prev = NULL;
}
ci = mrb->c->ci;
mrb->c->stack = ci->stackent;
mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1;
while (ci > mrb->c->ci) {
if (ci[-1].acc == CI_ACC_SKIP) {
......
##
# ensure Test
assert('ensure - context - yield') do
class EnsureYieldBreak
attr_reader :ensure_context
def try
yield
ensure
@ensure_context = self
end
end
yielder = EnsureYieldBreak.new
yielder.try do
end
assert_equal yielder, yielder.ensure_context
end
assert('ensure - context - yield and break') do
class EnsureYieldBreak
attr_reader :ensure_context
def try
yield
ensure
@ensure_context = self
end
end
yielder = EnsureYieldBreak.new
yielder.try do
break
end
assert_equal yielder, yielder.ensure_context
end
assert('ensure - context - yield and return') do
class EnsureYieldBreak
attr_reader :ensure_context
def try
yield
ensure
@ensure_context = self
end
end
yielder = EnsureYieldBreak.new
lambda do
yielder.try do
return
end
end.call
assert_equal yielder, yielder.ensure_context
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment