summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-08 14:38:43 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-08 14:38:43 +0000
commit4c1f8acd2ac14ffce1e1d9f414c700f293a7bdc6 (patch)
treedaa0944e91cc2bb3858eae18fde3d44630aa07b9
parent555035a349bb9d7659317dc65dc68ce6e2e6aaa7 (diff)
merge revision(s) 40583,40584,40585,40590: [Backport #8367]
* insns.def (defined): get method entry from the method top level frame, not block frame. [ruby-core:54769] [Bug #8367] * insns.def (defined): use vm_search_superclass() like as normal super call. based on a patch <https://gist.github.com/wanabe/5520026> by wanabe. * vm_insnhelper.c (vm_search_superclass): return error but not raise exceptions. * vm_insnhelper.c (vm_search_super_method): check the result of vm_search_superclass and raise execptions on error. vm_search_superclass and raise exceptions on error. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@40613 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog17
-rw-r--r--insns.def8
-rw-r--r--test/ruby/test_defined.rb21
-rw-r--r--version.h2
-rw-r--r--vm_insnhelper.c22
5 files changed, 59 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e0d8204ad..d629418aba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+Wed May 8 23:07:19 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * insns.def (defined): use vm_search_superclass() like as normal super
+ call. based on a patch <https://gist.github.com/wanabe/5520026> by
+ wanabe.
+
+ * vm_insnhelper.c (vm_search_superclass): return error but not raise
+ exceptions.
+
+ * vm_insnhelper.c (vm_search_super_method): check the result of
+ vm_search_superclass and raise exceptions on error.
+
+Wed May 8 23:07:19 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * insns.def (defined): get method entry from the method top level
+ frame, not block frame. [ruby-core:54769] [Bug #8367]
+
Wed May 8 01:18:41 2013 Tanaka Akira <akr@fsij.org>
* internal.h (MUL_OVERFLOW_SIGNED_INTEGER_P): New macro.
diff --git a/insns.def b/insns.def
index a36d659364..3d518d0489 100644
--- a/insns.def
+++ b/insns.def
@@ -764,10 +764,10 @@ defined
}
break;
case DEFINED_ZSUPER:{
- const rb_method_entry_t *me = GET_CFP()->me;
- if (me) {
- VALUE klass = vm_search_normal_superclass(GET_CFP()->klass);
- ID id = me->def ? me->def->original_id : me->called_id;
+ rb_call_info_t cit;
+ if (vm_search_superclass(GET_CFP(), GET_ISEQ(), Qnil, &cit) == 0) {
+ VALUE klass = cit.klass;
+ ID id = cit.mid;
if (rb_method_boundp(klass, id, 0)) {
expr_type = DEFINED_ZSUPER;
}
diff --git a/test/ruby/test_defined.rb b/test/ruby/test_defined.rb
index fe985340c1..84f3388e29 100644
--- a/test/ruby/test_defined.rb
+++ b/test/ruby/test_defined.rb
@@ -1,4 +1,5 @@
require 'test/unit'
+require_relative 'envutil'
class TestDefined < Test::Unit::TestCase
class Foo
@@ -181,4 +182,24 @@ class TestDefined < Test::Unit::TestCase
end
assert_equal("super", c.new.m)
end
+
+ def test_super_in_block
+ bug8367 = '[ruby-core:54769] [Bug #8367]'
+ c = Class.new do
+ def x; end
+ end
+
+ m = Module.new do
+ def b; yield; end
+ def x; b {return defined?(super)}; end
+ end
+
+ o = c.new
+ o.extend(m)
+ assert_equal("super", o.x)
+ end
+
+ def test_super_toplevel
+ assert_separately([], "assert_nil(defined?(super))")
+ end
end
diff --git a/version.h b/version.h
index d835c1edf9..0612099913 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.0.0"
#define RUBY_RELEASE_DATE "2013-05-08"
-#define RUBY_PATCHLEVEL 187
+#define RUBY_PATCHLEVEL 188
#define RUBY_RELEASE_YEAR 2013
#define RUBY_RELEASE_MONTH 5
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index ec26f677ff..0c52774ca8 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1927,7 +1927,7 @@ vm_super_outside(void)
rb_raise(rb_eNoMethodError, "super called outside of method");
}
-static void
+static int
vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval, rb_call_info_t *ci)
{
while (iseq && !iseq->klass) {
@@ -1935,7 +1935,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
}
if (iseq == 0) {
- vm_super_outside();
+ return -1;
}
ci->mid = iseq->defined_method_id;
@@ -1946,7 +1946,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
if (!sigval) {
/* zsuper */
- rb_raise(rb_eRuntimeError, "implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly.");
+ return -2;
}
while (lcfp->iseq != iseq) {
@@ -1955,7 +1955,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
while (1) {
lcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(lcfp);
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, lcfp)) {
- vm_super_outside();
+ return -1;
}
if (lcfp->ep == tep) {
break;
@@ -1965,7 +1965,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
/* temporary measure for [Bug #2420] [Bug #3136] */
if (!lcfp->me) {
- vm_super_outside();
+ return -1;
}
ci->mid = lcfp->me->def->original_id;
@@ -1974,6 +1974,8 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
else {
ci->klass = vm_search_normal_superclass(reg_cfp->klass);
}
+
+ return 0;
}
static void
@@ -2003,7 +2005,15 @@ vm_search_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_inf
rb_obj_classname(ci->recv), rb_class2name(m));
}
- vm_search_superclass(GET_CFP(), iseq, sigval, ci);
+ switch (vm_search_superclass(GET_CFP(), iseq, sigval, ci)) {
+ case -1:
+ vm_super_outside();
+ case -2:
+ rb_raise(rb_eRuntimeError,
+ "implicit argument passing of super from method defined"
+ " by define_method() is not supported."
+ " Specify all arguments explicitly.");
+ }
/* TODO: use inline cache */
ci->me = rb_method_entry(ci->klass, ci->mid, &ci->defined_class);