summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--test/ruby/test_eval.rb15
-rw-r--r--vm_insnhelper.c20
3 files changed, 31 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 17fb409f90..e030dfa0f7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Thu Sep 23 09:01:28 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * vm_insnhelper.c (vm_cref_push): no outer cref is needed for proc
+ from method. Bug #3786, Bug #3860, [ruby-core:32501]
+
Wed Sep 22 17:12:01 2010 Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
* test/openssl/utils.rb (OpenSSL#silent): always restore $VERBOSE.
diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb
index a6900e075e..299165fb34 100644
--- a/test/ruby/test_eval.rb
+++ b/test/ruby/test_eval.rb
@@ -415,4 +415,19 @@ class TestEval < Test::Unit::TestCase
assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-32be"))}
assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-32le"))}
end
+
+ def test_instance_eval_method_proc
+ bug3860 = Class.new do
+ def initialize(a);
+ @a=a
+ end
+ def get(*args)
+ @a
+ end
+ end
+ foo = bug3860.new 1
+ foo_pr = foo.method(:get).to_proc
+ result = foo.instance_eval(&foo_pr)
+ assert_equal(1, result, 'Bug #3786, Bug #3860, [ruby-core:32501]')
+ end
end
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 985a2fb5a8..ba3b0cbb37 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1053,21 +1053,23 @@ vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type)
}
static NODE *
-vm_get_cref(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
+vm_get_cref0(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
{
- NODE *cref = 0;
-
while (1) {
if (lfp == dfp) {
- cref = iseq->cref_stack;
- break;
+ return iseq->cref_stack;
}
else if (dfp[-1] != Qnil) {
- cref = (NODE *)dfp[-1];
- break;
+ return (NODE *)dfp[-1];
}
dfp = GET_PREV_DFP(dfp);
}
+}
+
+static NODE *
+vm_get_cref(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
+{
+ NODE *cref = vm_get_cref0(iseq, lfp, dfp);
if (cref == 0) {
rb_bug("vm_get_cref: unreachable");
@@ -1084,10 +1086,10 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
cref->nd_visi = noex;
if (blockptr) {
- cref->nd_next = vm_get_cref(blockptr->iseq, blockptr->lfp, blockptr->dfp);
+ cref->nd_next = vm_get_cref0(blockptr->iseq, blockptr->lfp, blockptr->dfp);
}
else if (cfp) {
- cref->nd_next = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
+ cref->nd_next = vm_get_cref0(cfp->iseq, cfp->lfp, cfp->dfp);
}
return cref;