Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

make sure Kernel#respond_to? doesn't call itself stupid^Wrecursively

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@2947 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
commit 28db59879a4564490618efa8de39d043117644d0 1 parent 4f618cc
Laurent Sansonetti authored
Showing with 34 additions and 12 deletions.
  1. +21 −6 dispatcher.cpp
  2. +1 −0  vm.h
  3. +12 −6 vm_method.c
View
27 dispatcher.cpp
@@ -1757,16 +1757,17 @@ rb_vm_get_method(VALUE klass, VALUE obj, ID mid, int scope)
extern IMP basic_respond_to_imp; // vm_method.c
-extern "C"
-bool
-rb_vm_respond_to(VALUE obj, SEL sel, bool priv)
+static bool
+respond_to(VALUE obj, SEL sel, bool priv, bool check_override)
{
VALUE klass = CLASS_OF(obj);
- IMP respond_to_imp = class_getMethodImplementation((Class)klass,
- selRespondTo);
+ const bool overriden = check_override
+ ? (class_getMethodImplementation((Class)klass, selRespondTo)
+ != basic_respond_to_imp)
+ : false;
- if (respond_to_imp == basic_respond_to_imp) {
+ if (!overriden) {
// FIXME: too slow!
bool reject_pure_ruby_methods = false;
Method m = class_getInstanceMethod((Class)klass, sel);
@@ -1802,3 +1803,17 @@ rb_vm_respond_to(VALUE obj, SEL sel, bool priv)
return rb_vm_call(obj, selRespondTo, n, args, false) == Qtrue;
}
}
+
+extern "C"
+bool
+rb_vm_respond_to(VALUE obj, SEL sel, bool priv)
+{
+ return respond_to(obj, sel, priv, true);
+}
+
+extern "C"
+bool
+rb_vm_respond_to2(VALUE obj, SEL sel, bool priv, bool check_override)
+{
+ return respond_to(obj, sel, priv, check_override);
+}
View
1  vm.h
@@ -300,6 +300,7 @@ void *rb_vm_get_call_cache(SEL sel);
VALUE rb_vm_yield(int argc, const VALUE *argv);
VALUE rb_vm_yield_under(VALUE klass, VALUE self, int argc, const VALUE *argv);
bool rb_vm_respond_to(VALUE obj, SEL sel, bool priv);
+bool rb_vm_respond_to2(VALUE obj, SEL sel, bool priv, bool check_override);
VALUE rb_vm_method_missing(VALUE obj, int argc, const VALUE *argv);
void rb_vm_push_methods(VALUE ary, VALUE mod, bool include_objc_methods,
int (*filter) (VALUE, ID, VALUE));
View
18 vm_method.c
@@ -769,24 +769,30 @@ rb_mod_modfunc(VALUE module, SEL sel, int argc, VALUE *argv)
//static NODE *basic_respond_to = 0;
-bool
-rb_obj_respond_to(VALUE obj, ID id, bool priv)
+static bool
+rb_obj_respond_to2(VALUE obj, ID id, bool priv, bool check_override)
{
const char *id_name = rb_id2name(id);
SEL sel = sel_registerName(id_name);
- if (!rb_vm_respond_to(obj, sel, priv)) {
+ if (!rb_vm_respond_to2(obj, sel, priv, check_override)) {
char buf[100];
snprintf(buf, sizeof buf, "%s:", id_name);
sel = sel_registerName(buf);
- return rb_vm_respond_to(obj, sel, priv);
+ return rb_vm_respond_to2(obj, sel, priv, check_override);
}
return true;
}
bool
+rb_obj_respond_to(VALUE obj, ID id, bool priv)
+{
+ return rb_obj_respond_to2(obj, id, priv, true);
+}
+
+bool
rb_respond_to(VALUE obj, ID id)
{
- return rb_obj_respond_to(obj, id, Qfalse);
+ return rb_obj_respond_to(obj, id, false);
}
/*
@@ -806,7 +812,7 @@ obj_respond_to(VALUE obj, SEL sel, int argc, VALUE *argv)
rb_scan_args(argc, argv, "11", &mid, &priv);
id = rb_to_id(mid);
- return rb_obj_respond_to(obj, id, RTEST(priv)) ? Qtrue : Qfalse;
+ return rb_obj_respond_to2(obj, id, RTEST(priv), false) ? Qtrue : Qfalse;
}
IMP basic_respond_to_imp = NULL;
Please sign in to comment.
Something went wrong with that request. Please try again.