[前][次][番号順一覧][スレッド一覧]

ruby-changes:13765

From: matz <ko1@a...>
Date: Fri, 30 Oct 2009 02:16:24 +0900 (JST)
Subject: [ruby-changes:13765] Ruby:r25560 (trunk): * enum.c (enum_count): call #size using rb_funcall_no_recursive()

matz	2009-10-30 02:16:05 +0900 (Fri, 30 Oct 2009)

  New Revision: 25560

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25560

  Log:
    * 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]

  Modified files:
    trunk/ChangeLog
    trunk/enum.c
    trunk/eval.c
    trunk/vm_eval.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 25559)
+++ ChangeLog	(revision 25560)
@@ -1,3 +1,13 @@
+Fri Oct 30 02:11:36 2009  Yukihiro Matsumoto  <matz@r...>
+
+	* 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]
+
 Thu Oct 29 18:37:02 2009  NARUSE, Yui  <naruse@r...>
 
 	* encoding.c (Init_Encoding): revert previous commit.
Index: enum.c
===================================================================
--- enum.c	(revision 25559)
+++ enum.c	(revision 25560)
@@ -119,6 +119,8 @@
     return Qnil;
 }
 
+extern VALUE rb_funcall_no_recursive(VALUE, ID, int, VALUE*, VALUE (*)());
+
 /*
  *  call-seq:
  *     enum.count                   => int
@@ -150,8 +152,8 @@
 	}
 	else {
 	    VALUE tmp;
-
-	    tmp = rb_check_funcall(obj, id_size, 0, 0);
+	    
+	    tmp = rb_funcall_no_recursive(obj, id_size, 0, 0, enum_count);
 	    if (tmp != Qundef) return tmp;
 	    func = count_all_i;
 	}
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 25559)
+++ vm_eval.c	(revision 25560)
@@ -536,7 +536,49 @@
     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)
 {
     VALUE vid;
Index: eval.c
===================================================================
--- eval.c	(revision 25559)
+++ eval.c	(revision 25560)
@@ -492,39 +492,7 @@
     return Qnil;		/* not reached */
 }
 
-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);
-}
-
-static VALUE
 make_exception(int argc, VALUE *argv, int isstr)
 {
     VALUE mesg;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]