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

ruby-changes:40424

From: nobu <ko1@a...>
Date: Mon, 9 Nov 2015 21:48:38 +0900 (JST)
Subject: [ruby-changes:40424] nobu:r52505 (trunk): vm_eval.c: rb_check_funcall_default

nobu	2015-11-09 21:48:20 +0900 (Mon, 09 Nov 2015)

  New Revision: 52505

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

  Log:
    vm_eval.c: rb_check_funcall_default
    
    * vm_eval.c (rb_check_funcall_default): split from
      rb_check_funcall to return the given fallback value.
    * object.c (rb_obj_dig): use rb_check_funcall_default so that tail
      call optimization will be possible.  [Feature #11643]

  Modified files:
    trunk/ChangeLog
    trunk/internal.h
    trunk/object.c
    trunk/vm_eval.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 52504)
+++ ChangeLog	(revision 52505)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Nov  9 21:48:17 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* vm_eval.c (rb_check_funcall_default): split from
+	  rb_check_funcall to return the given fallback value.
+
+	* object.c (rb_obj_dig): use rb_check_funcall_default so that tail
+	  call optimization will be possible.  [Feature #11643]
+
 Mon Nov  9 21:27:23 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* array.c (rb_ary_dig): new method Array#dig.
Index: object.c
===================================================================
--- object.c	(revision 52504)
+++ object.c	(revision 52505)
@@ -3183,9 +3183,7 @@ rb_obj_dig(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/object.c#L3183
 		}
 	    }
 	}
-	obj = rb_check_funcall(obj, id_dig, argc, argv);
-	if (obj == Qundef) return notfound;
-	break;
+	return rb_check_funcall_default(obj, id_dig, argc, argv, notfound);
     }
     return obj;
 }
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 52504)
+++ vm_eval.c	(revision 52505)
@@ -410,7 +410,7 @@ check_funcall_callable(rb_thread_t *th, https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L410
 }
 
 static VALUE
-check_funcall_missing(rb_thread_t *th, VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int respond)
+check_funcall_missing(rb_thread_t *th, VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int respond, VALUE def)
 {
     struct rescue_funcall_args args;
     const rb_method_entry_t *me;
@@ -418,10 +418,10 @@ check_funcall_missing(rb_thread_t *th, V https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L418
 
     ret = basic_obj_respond_to_missing(th, klass, recv,
 				       ID2SYM(mid), PRIV);
-    if (!RTEST(ret)) return Qundef;
+    if (!RTEST(ret)) return def;
     args.respond = respond > 0;
     args.respond_to_missing = (ret != Qundef);
-    ret = Qundef;
+    ret = def;
     me = method_entry_get(klass, idMethodMissing, &args.defined_class);
     if (me && !METHOD_ENTRY_BASIC(me)) {
 	VALUE argbuf, *new_args = ALLOCV_N(VALUE, argbuf, argc+1);
@@ -446,17 +446,24 @@ check_funcall_missing(rb_thread_t *th, V https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L446
 VALUE
 rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
 {
+    return rb_check_funcall_default(recv, mid, argc, argv, Qundef);
+}
+
+VALUE
+rb_check_funcall_default(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def)
+{
     VALUE klass = CLASS_OF(recv);
     const rb_callable_method_entry_t *me;
     rb_thread_t *th = GET_THREAD();
     int respond = check_funcall_respond_to(th, klass, recv, mid);
 
     if (!respond)
-	return Qundef;
+	return def;
 
     me = rb_search_method_entry(recv, mid);
     if (!check_funcall_callable(th, me)) {
-	return check_funcall_missing(th, klass, recv, mid, argc, argv, respond);
+	return check_funcall_missing(th, klass, recv, mid, argc, argv,
+				     respond, def);
     }
     stack_check();
     return vm_call0(th, recv, mid, argc, argv, me);
@@ -477,7 +484,8 @@ rb_check_funcall_with_hook(VALUE recv, I https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L484
     me = rb_search_method_entry(recv, mid);
     if (!check_funcall_callable(th, me)) {
 	(*hook)(FALSE, recv, mid, argc, argv, arg);
-	return check_funcall_missing(th, klass, recv, mid, argc, argv, respond);
+	return check_funcall_missing(th, klass, recv, mid, argc, argv,
+				     respond, Qundef);
     }
     stack_check();
     (*hook)(TRUE, recv, mid, argc, argv, arg);
Index: internal.h
===================================================================
--- internal.h	(revision 52504)
+++ internal.h	(revision 52505)
@@ -1218,6 +1218,7 @@ VALUE rb_check_block_call(VALUE, ID, int https://github.com/ruby/ruby/blob/trunk/internal.h#L1218
 typedef void rb_check_funcall_hook(int, VALUE, ID, int, const VALUE *, VALUE);
 VALUE rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv,
 				 rb_check_funcall_hook *hook, VALUE arg);
+VALUE rb_check_funcall_default(VALUE, ID, int, const VALUE *, VALUE);
 VALUE rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, int *stateptr);
 VALUE rb_yield_1(VALUE val);
 

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

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