summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-27 16:03:12 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-27 16:03:12 +0000
commit69eab6991a64b6dff4209f96d719680a875b0d89 (patch)
tree118d9f1770ef9d22f0af8f4a1437c96580e15a2e /object.c
parent41fd33e5fe22f13fd178c50adaee39ce53a3c155 (diff)
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
Diffstat (limited to 'object.c')
-rw-r--r--object.c32
1 files changed, 21 insertions, 11 deletions
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;
}