From bb504213816e4598f1961b99e115f8ba59bef71f Mon Sep 17 00:00:00 2001 From: shugo Date: Fri, 2 Nov 2012 05:48:29 +0000 Subject: * string.c (sym_to_proc, sym_call): A Proc created by Symbol#to_proc should close over the current refinements. [ruby-dev:46345] [Bug #7261] * vm_eval.c (rb_call0, rb_search_method_entry, rb_funcall_passing_block_with_refinements): add a new argument `refinements' for the above changes. * test/ruby/test_refinement.rb: related test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37418 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- vm_eval.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'vm_eval.c') diff --git a/vm_eval.c b/vm_eval.c index 64cd9283d3..756e49bdf4 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -266,7 +266,8 @@ stack_check(void) } static inline rb_method_entry_t * - rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr); + rb_search_method_entry(VALUE refinements, VALUE recv, ID mid, + VALUE *defined_class_ptr); static inline int rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self); #define NOEX_OK NOEX_NOSUPER @@ -286,10 +287,11 @@ static inline int rb_method_call_status(rb_thread_t *th, const rb_method_entry_t */ static inline VALUE rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv, - call_type scope, VALUE self) + call_type scope, VALUE self, VALUE refinements) { VALUE defined_class; - rb_method_entry_t *me = rb_search_method_entry(recv, mid, &defined_class); + rb_method_entry_t *me = + rb_search_method_entry(refinements, recv, mid, &defined_class); rb_thread_t *th = GET_THREAD(); int call_status = rb_method_call_status(th, me, scope, self); @@ -353,7 +355,7 @@ check_funcall(VALUE recv, ID mid, int argc, VALUE *argv) } } - me = rb_search_method_entry(recv, mid, &defined_class); + me = rb_search_method_entry(Qnil, recv, mid, &defined_class); call_status = rb_method_call_status(th, me, CALL_FCALL, Qundef); if (call_status != NOEX_OK) { if (rb_method_basic_definition_p(klass, idMethodMissing)) { @@ -418,7 +420,8 @@ rb_type_str(enum ruby_value_type type) } static inline rb_method_entry_t * -rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr) +rb_search_method_entry(VALUE refinements, VALUE recv, ID mid, + VALUE *defined_class_ptr) { VALUE klass = CLASS_OF(recv); @@ -457,7 +460,8 @@ rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr) rb_id2name(mid), type, (void *)recv, flags, klass); } } - return rb_method_entry_get_with_refinements(Qnil, klass, mid, defined_class_ptr); + return rb_method_entry_get_with_refinements(refinements, klass, mid, + defined_class_ptr); } static inline int @@ -521,7 +525,7 @@ rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type sc static inline VALUE rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope) { - return rb_call0(recv, mid, argc, argv, scope, Qundef); + return rb_call0(recv, mid, argc, argv, scope, Qundef, Qnil); } NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, @@ -769,6 +773,17 @@ rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv) return rb_call(recv, mid, argc, argv, CALL_PUBLIC); } +VALUE +rb_funcall_passing_block_with_refinements(VALUE recv, ID mid, int argc, + const VALUE *argv, + VALUE refinements) +{ + PASS_PASSED_BLOCK_TH(GET_THREAD()); + + return rb_call0(recv, mid, argc, argv, CALL_PUBLIC, Qundef, + refinements); +} + static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope) { @@ -793,7 +808,7 @@ send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope) id = rb_to_id(vid); } PASS_PASSED_BLOCK_TH(th); - return rb_call0(recv, id, argc, argv, scope, self); + return rb_call0(recv, id, argc, argv, scope, self, Qnil); } /* -- cgit v1.2.3