ruby-changes:61472
From: Nobuyoshi <ko1@a...>
Date: Thu, 4 Jun 2020 02:13:15 +0900 (JST)
Subject: [ruby-changes:61472] 184f78314e (master): Properly resolve refinements in defined? on private call [Bug #16932]
https://git.ruby-lang.org/ruby.git/commit/?id=184f78314e From 184f78314e98cab63e7503cead4a4e99bd132a08 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Wed, 3 Jun 2020 23:06:06 +0900 Subject: Properly resolve refinements in defined? on private call [Bug #16932] diff --git a/internal/vm.h b/internal/vm.h index 152f136..657202b 100644 --- a/internal/vm.h +++ b/internal/vm.h @@ -95,6 +95,12 @@ MJIT_SYMBOL_EXPORT_BEGIN https://github.com/ruby/ruby/blob/trunk/internal/vm.h#L95 void rb_vm_search_method_slowpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass); MJIT_SYMBOL_EXPORT_END +/* vm_method.c */ +struct rb_execution_context_struct; +MJIT_SYMBOL_EXPORT_BEGIN +int rb_ec_obj_respond_to(struct rb_execution_context_struct *ec, VALUE obj, ID id, int priv); +MJIT_SYMBOL_EXPORT_END + /* vm_dump.c */ void rb_print_backtrace(void); diff --git a/test/ruby/test_defined.rb b/test/ruby/test_defined.rb index 6ad4854..b22db70 100644 --- a/test/ruby/test_defined.rb +++ b/test/ruby/test_defined.rb @@ -309,24 +309,45 @@ class TestDefined < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_defined.rb#L309 refine RefinedClass do def pub end + + private + + def priv + end end def self.call_without_using(x = RefinedClass.new) defined?(x.pub) end + def self.vcall_without_using(x = RefinedClass.new) + x.instance_eval {defined?(priv)} + end + using self def self.call_with_using(x = RefinedClass.new) defined?(x.pub) end + + def self.vcall_with_using(x = RefinedClass.new) + x.instance_eval {defined?(priv)} + end end def test_defined_refined_call_without_using assert(!RefiningModule.call_without_using, "refined public method without using") end + def test_defined_refined_vcall_without_using + assert(!RefiningModule.vcall_without_using, "refined private method without using") + end + def test_defined_refined_call_with_using assert(RefiningModule.call_with_using, "refined public method with using") end + + def test_defined_refined_vcall_with_using + assert(RefiningModule.vcall_with_using, "refined private method with using") + end end diff --git a/vm_insnhelper.c b/vm_insnhelper.c index f910c03..f8936b3 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -3651,12 +3651,9 @@ vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_ https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3651 } case DEFINED_FUNC: klass = CLASS_OF(v); - if (rb_method_boundp(klass, SYM2ID(obj), 0)) { + if (rb_ec_obj_respond_to(ec, v, SYM2ID(obj), TRUE)) { expr_type = DEFINED_METHOD; } - else { - expr_type = check_respond_to_missing(obj, v); - } break; case DEFINED_METHOD:{ VALUE klass = CLASS_OF(v); diff --git a/vm_method.c b/vm_method.c index a87a8f3..f1b71a1 100644 --- a/vm_method.c +++ b/vm_method.c @@ -2358,6 +2358,12 @@ int https://github.com/ruby/ruby/blob/trunk/vm_method.c#L2358 rb_obj_respond_to(VALUE obj, ID id, int priv) { rb_execution_context_t *ec = GET_EC(); + return rb_ec_obj_respond_to(ec, obj, id, priv); +} + +int +rb_ec_obj_respond_to(rb_execution_context_t *ec, VALUE obj, ID id, int priv) +{ VALUE klass = CLASS_OF(obj); int ret = vm_respond_to(ec, klass, obj, id, priv); if (ret == -1) ret = basic_obj_respond_to(ec, obj, id, !priv); -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/