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/