From 69eab6991a64b6dff4209f96d719680a875b0d89 Mon Sep 17 00:00:00 2001 From: nagachika Date: Tue, 27 May 2014 16:03:12 +0000 Subject: merge revision(s) r45179,r45564,r45565,r45584,r45585: [Backport #9721] envutil.rb: move labeled_module and labeled_class * test/ruby/envutil.rb (labeled_module, labeled_class): move from test/ruby/test_module.rb. * proc.c (rb_method_call_with_block, umethod_bind): call with IClass including the module for a module instance method. [ruby-core:61936] [Bug #9721] * vm_insnhelper.c (vm_search_super_method): allow bound UnboundMethod case. * proc.c (umethod_bind): use the ancestor iclass instead of new iclass to get rid of infinite recursion, if the defined module is already included. [ruby-core:62014] [Bug #9721] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@46190 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- object.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'object.c') diff --git a/object.c b/object.c index bb43b4617e..3885d9bf70 100644 --- a/object.c +++ b/object.c @@ -584,6 +584,8 @@ class_or_module_required(VALUE c) return c; } +static VALUE class_search_ancestor(VALUE cl, VALUE c); + /* * call-seq: * obj.instance_of?(class) -> true or false @@ -644,15 +646,27 @@ rb_obj_is_kind_of(VALUE obj, VALUE c) VALUE cl = CLASS_OF(obj); c = class_or_module_required(c); - c = RCLASS_ORIGIN(c); + return class_search_ancestor(cl, RCLASS_ORIGIN(c)) ? Qtrue : Qfalse; +} + +static VALUE +class_search_ancestor(VALUE cl, VALUE c) +{ while (cl) { if (cl == c || RCLASS_M_TBL_WRAPPER(cl) == RCLASS_M_TBL_WRAPPER(c)) - return Qtrue; + return cl; cl = RCLASS_SUPER(cl); } - return Qfalse; + return 0; } +VALUE +rb_class_search_ancestor(VALUE cl, VALUE c) +{ + cl = class_or_module_required(cl); + c = class_or_module_required(c); + return class_search_ancestor(cl, RCLASS_ORIGIN(c)); +} /* * call-seq: @@ -1548,16 +1562,12 @@ rb_class_inherited_p(VALUE mod, VALUE arg) rb_raise(rb_eTypeError, "compared with non class/module"); } arg = RCLASS_ORIGIN(arg); - while (mod) { - if (RCLASS_M_TBL_WRAPPER(mod) == RCLASS_M_TBL_WRAPPER(arg)) - return Qtrue; - mod = RCLASS_SUPER(mod); + if (class_search_ancestor(mod, arg)) { + return Qtrue; } /* not mod < arg; check if mod > arg */ - while (arg) { - if (RCLASS_M_TBL_WRAPPER(arg) == RCLASS_M_TBL_WRAPPER(start)) - return Qfalse; - arg = RCLASS_SUPER(arg); + if (class_search_ancestor(arg, start)) { + return Qfalse; } return Qnil; } -- cgit v1.2.3