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

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/

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