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

ruby-changes:39565

From: nobu <ko1@a...>
Date: Thu, 20 Aug 2015 14:13:50 +0900 (JST)
Subject: [ruby-changes:39565] nobu:r51646 (trunk): vm_eval.c: share with rb_obj_respond_to

nobu	2015-08-20 14:13:28 +0900 (Thu, 20 Aug 2015)

  New Revision: 51646

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

  Log:
    vm_eval.c: share with rb_obj_respond_to
    
    * vm_eval.c (check_funcall_respond_to): share the behavior with
      rb_obj_respond_to.  [ruby-core:70460] [Bug #11465]
    * vm_method.c (vm_respond_to): extract from rb_obj_respond_to and
      merge r39881.

  Modified files:
    trunk/ChangeLog
    trunk/test/ruby/test_array.rb
    trunk/vm_eval.c
    trunk/vm_method.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 51645)
+++ ChangeLog	(revision 51646)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Aug 20 14:13:27 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* vm_eval.c (check_funcall_respond_to): share the behavior with
+	  rb_obj_respond_to.  [ruby-core:70460] [Bug #11465]
+
+	* vm_method.c (vm_respond_to): extract from rb_obj_respond_to and
+	  merge r39881.
+
 Thu Aug 20 08:53:09 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* vm_method.c (rb_obj_respond_to): reuse found method entry
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 51645)
+++ vm_eval.c	(revision 51646)
@@ -378,27 +378,7 @@ check_funcall_failed(struct rescue_funca https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L378
 static int
 check_funcall_respond_to(rb_thread_t *th, VALUE klass, VALUE recv, ID mid)
 {
-    const rb_callable_method_entry_t *me = rb_callable_method_entry(klass, idRespond_to);
-
-    if (me && !METHOD_ENTRY_BASIC(me)) {
-	const rb_block_t *passed_block = th->passed_block;
-	VALUE args[2], result;
-	int arity = rb_method_entry_arity((const rb_method_entry_t *)me);
-
-	if (arity > 2)
-	    rb_raise(rb_eArgError, "respond_to? must accept 1 or 2 arguments (requires %d)", arity);
-
-	if (arity < 1) arity = 2;
-
-	args[0] = ID2SYM(mid);
-	args[1] = Qtrue;
-	result = vm_call0(th, recv, idRespond_to, arity, args, me);
-	th->passed_block = passed_block;
-	if (!RTEST(result)) {
-	    return FALSE;
-	}
-    }
-    return TRUE;
+    return vm_respond_to(th, klass, recv, mid, 1);
 }
 
 static int
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 51645)
+++ vm_method.c	(revision 51646)
@@ -1829,10 +1829,9 @@ basic_obj_respond_to(VALUE obj, ID id, i https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1829
     }
 }
 
-int
-rb_obj_respond_to(VALUE obj, ID id, int priv)
+static int
+vm_respond_to(rb_thread_t *th, VALUE klass, VALUE obj, ID id, int priv)
 {
-    VALUE klass = CLASS_OF(obj);
     VALUE defined_class;
     const ID resid = idRespond_to;
     const rb_method_entry_t *const me =
@@ -1845,12 +1844,20 @@ rb_obj_respond_to(VALUE obj, ID id, int https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1844
     else {
 	int argc = 1;
 	VALUE args[2];
+	VALUE result;
 	const rb_callable_method_entry_t *cme;
+	const rb_block_t *passed_block = th->passed_block;
 
 	args[0] = ID2SYM(id);
 	args[1] = Qtrue;
 	if (priv) {
-	    if (rb_method_entry_arity(me) != 1) {
+	    argc = rb_method_entry_arity(me);
+	    if (argc > 2) {
+		rb_raise(rb_eArgError,
+			 "respond_to? must accept 1 or 2 arguments (requires %d)",
+			 argc);
+	    }
+	    if (argc != 1) {
 		argc = 2;
 	    }
 	    else if (!NIL_P(ruby_verbose)) {
@@ -1871,11 +1878,19 @@ rb_obj_respond_to(VALUE obj, ID id, int https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1878
 	    }
 	}
 	cme = prepare_callable_method_entry(defined_class, resid, me);
-	return RTEST(vm_call0(GET_THREAD(), obj, resid, argc, args, cme));
+	result = vm_call0(th, obj, resid, argc, args, cme);
+	th->passed_block = passed_block;
+	return RTEST(result);
     }
 }
 
 int
+rb_obj_respond_to(VALUE obj, ID id, int priv)
+{
+    return vm_respond_to(GET_THREAD(), CLASS_OF(obj), obj, id, priv);
+}
+
+int
 rb_respond_to(VALUE obj, ID id)
 {
     return rb_obj_respond_to(obj, id, FALSE);
Index: test/ruby/test_array.rb
===================================================================
--- test/ruby/test_array.rb	(revision 51645)
+++ test/ruby/test_array.rb	(revision 51646)
@@ -855,6 +855,28 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L855
     assert_match(/reentered/, e.message, '[ruby-dev:34798]')
   end
 
+  def test_flatten_respond_to_missing
+    bug11465 = '[ruby-core:70460] [Bug #11465]'
+
+    obj = Class.new do
+      def respond_to_missing?(method, stuff)
+        return false if method == :to_ary
+        super
+      end
+
+      def method_missing(*args)
+        super
+      end
+    end.new
+
+    ex = nil
+    trace = TracePoint.new(:raise) do |tp|
+      ex = tp.raised_exception
+    end
+    trace.enable {[obj].flatten}
+    assert_nil(ex, bug11465)
+  end
+
   def test_permutation_with_callcc
     need_continuation
     n = 1000

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

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