summaryrefslogtreecommitdiffstats
path: root/vm_eval.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-10-29 17:16:05 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-10-29 17:16:05 +0000
commit2a7a7264745900bd50fa70a8e3f906446d16767d (patch)
treebc6299ca6771ec0811ce6b11331987b4ebf0ca46 /vm_eval.c
parente2ef9d113910d66e5293ca750ca28fb20bee3c3c (diff)
downloadruby-2a7a7264745900bd50fa70a8e3f906446d16767d.tar.gz
ruby-2a7a7264745900bd50fa70a8e3f906446d16767d.tar.xz
ruby-2a7a7264745900bd50fa70a8e3f906446d16767d.zip
* enum.c (enum_count): call #size using rb_funcall_no_recursive()
to prevent infinite recursive calls. [ruby-core:24794] * vm_eval.c (rb_funcall_no_recursive): utility function to check direct recursive call. * vm_eval.c (rb_check_funcall): move from eval.c. [refactoring] git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@25560 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_eval.c')
-rw-r--r--vm_eval.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/vm_eval.c b/vm_eval.c
index 8fbe82d10..309f997a1 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -536,6 +536,48 @@ rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
}
+struct rescue_funcall_args {
+ VALUE obj;
+ ID id;
+ int argc;
+ VALUE *argv;
+};
+
+static VALUE
+check_funcall(struct rescue_funcall_args *args)
+{
+ return rb_funcall2(args->obj, args->id, args->argc, args->argv);
+}
+
+static VALUE
+check_failed(VALUE data)
+{
+ return data;
+}
+
+VALUE
+rb_check_funcall(VALUE obj, ID id, int argc, VALUE *argv)
+{
+ struct rescue_funcall_args args;
+
+ args.obj = obj;
+ args.id = id;
+ args.argc = argc;
+ args.argv = argv;
+ return rb_rescue2(check_funcall, (VALUE)&args, check_failed, Qundef,
+ rb_eNoMethodError, (VALUE)0);
+}
+
+VALUE
+rb_funcall_no_recursive(VALUE obj, ID id, int argc, VALUE *argv, VALUE (*func)())
+{
+ const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), id);
+ if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
+ me->def->body.cfunc.func == func)
+ return Qundef;
+ return rb_check_funcall(obj, id, argc, argv);
+}
+
static VALUE
send_internal(int argc, const VALUE *argv, VALUE recv, int scope)
{