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

ruby-changes:69188

From: Alan <ko1@a...>
Date: Thu, 21 Oct 2021 08:20:01 +0900 (JST)
Subject: [ruby-changes:69188] 3996e0ab07 (master): Add tests, comments, and an assert for invokesuper

https://git.ruby-lang.org/ruby.git/commit/?id=3996e0ab07

From 3996e0ab07d06b7685eecd56a542e9672702dee2 Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Wed, 23 Jun 2021 20:28:42 -0400
Subject: Add tests, comments, and an assert for invokesuper

---
 bootstraptest/test_yjit.rb | 57 ++++++++++++++++++++++++++++++++++++++++++++++
 yjit_codegen.c             |  6 ++++-
 yjit_iface.c               |  6 +++--
 3 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index fd1310b04e..fc0b693ec2 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1238,3 +1238,60 @@ assert_equal '[:A, [:A, :B]]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L1238
 
   C.new.bar
 }
+
+# Same invokesuper bytecode, multiple destinations
+assert_equal '[:Forward, :SecondTerminus]', %q{
+  module Terminus
+    def foo = :Terminus
+  end
+
+  module SecondTerminus
+    def foo = :SecondTerminus
+  end
+
+
+  module Forward
+    def foo = [:Forward, super]
+  end
+
+  class B
+    include SecondTerminus
+  end
+
+  class A < B
+    include Terminus
+    include Forward
+  end
+
+  A.new.foo
+  A.new.foo # compile
+
+  class B
+    include Forward
+    alias bar foo
+  end
+
+  # A.ancestors.take(5) == [A, Forward, Terminus, B, Forward, SecondTerminus]
+
+  A.new.bar
+}
+
+# invokesuper calling into itself
+assert_equal '[:B, [:B, :m]]', %q{
+  module M
+    def foo = :m
+  end
+
+  class B
+    include M
+    def foo = [:B, super]
+  end
+
+  ins = B.new
+  ins.singleton_class # materialize the singleton class
+  ins.foo
+  ins.foo # compile
+
+  ins.singleton_class.define_method(:bar, B.instance_method(:foo))
+  ins.bar
+}
diff --git a/yjit_codegen.c b/yjit_codegen.c
index 68fadfc820..d61206c2c1 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -2995,7 +2995,8 @@ gen_send(jitstate_t *jit, ctx_t *ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L2995
     return gen_send_general(jit, ctx, cd, block);
 }
 
-RBIMPL_ATTR_MAYBE_UNUSED() // not in use as it has problems in some situations.
+// Not in use as it's incorrect in some situations. See comments.
+RBIMPL_ATTR_MAYBE_UNUSED()
 static codegen_status_t
 gen_invokesuper(jitstate_t *jit, ctx_t *ctx)
 {
@@ -3096,6 +3097,9 @@ gen_invokesuper(jitstate_t *jit, ctx_t *ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L3097
     insn_opnd_t recv_opnd = OPND_STACK(argc);
     mov(cb, REG0, recv);
 
+    // FIXME: This guard and the assume_method_lookup_stable() call below isn't
+    // always enough to correctly replicate the interpreter's behavior of
+    // searching at runtime for the callee through the method entry of the stack frame.
     if (!jit_guard_known_klass(jit, ctx, comptime_recv_klass, recv_opnd, comptime_recv, SEND_MAX_DEPTH, side_exit)) {
         return YJIT_CANT_COMPILE;
     }
diff --git a/yjit_iface.c b/yjit_iface.c
index ba3e5bbb83..3d589f5e5e 100644
--- a/yjit_iface.c
+++ b/yjit_iface.c
@@ -218,8 +218,9 @@ add_lookup_dependency_i(st_data_t *key, st_data_t *value, st_data_t data, int ex https://github.com/ruby/ruby/blob/trunk/yjit_iface.c#L218
     return ST_CONTINUE;
 }
 
-// Remember that a block assumes that rb_callable_method_entry(receiver_klass, mid) == cme and that
-// cme is vald.
+// Remember that a block assumes that
+// `rb_callable_method_entry(receiver_klass, cme->called_id) == cme` and that
+// `cme` is valid.
 // When either of these assumptions becomes invalid, rb_yjit_method_lookup_change() or
 // rb_yjit_cme_invalidate() invalidates the block.
 //
@@ -230,6 +231,7 @@ assume_method_lookup_stable(VALUE receiver_klass, const rb_callable_method_entry https://github.com/ruby/ruby/blob/trunk/yjit_iface.c#L231
     RUBY_ASSERT(!block->receiver_klass && !block->callee_cme);
     RUBY_ASSERT(cme_validity_dependency);
     RUBY_ASSERT(method_lookup_dependency);
+    RUBY_ASSERT(rb_callable_method_entry(receiver_klass, cme->called_id) == cme);
     RUBY_ASSERT_ALWAYS(RB_TYPE_P(receiver_klass, T_CLASS));
     RUBY_ASSERT_ALWAYS(!rb_objspace_garbage_object_p(receiver_klass));
 
-- 
cgit v1.2.1


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

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