summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstraptest/test_yjit.rb32
-rw-r--r--yjit/src/codegen.rs19
2 files changed, 37 insertions, 14 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index cbb3f145b0..66b663b062 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1940,6 +1940,38 @@ assert_equal '[:A, :Btwo]', %q{
ins.foo
}
+# invokesuper with a block
+assert_equal 'true', %q{
+ class A
+ def foo = block_given?
+ end
+
+ class B < A
+ def foo = super()
+ end
+
+ B.new.foo { }
+ B.new.foo { }
+}
+
+# invokesuper in a block
+assert_equal '[0, 2]', %q{
+ class A
+ def foo(x) = x * 2
+ end
+
+ class B < A
+ def foo
+ 2.times.map do |x|
+ super(x)
+ end
+ end
+ end
+
+ B.new.foo
+ B.new.foo
+}
+
# Call to fixnum
assert_equal '[true, false]', %q{
def is_odd(obj)
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index be055c011b..8f439f9b0f 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -6623,22 +6623,15 @@ fn gen_invokesuper(
// Guard that the receiver has the same class as the one from compile time
let side_exit = get_side_exit(jit, ocb, ctx);
- let cfp = unsafe { get_ec_cfp(jit.ec.unwrap()) };
- let ep = unsafe { get_cfp_ep(cfp) };
- let cref_me = unsafe { *ep.offset(VM_ENV_DATA_INDEX_ME_CREF.try_into().unwrap()) };
- let me_as_value = VALUE(me as usize);
- if cref_me != me_as_value {
- // This will be the case for super within a block
- return CantCompile;
- }
-
asm.comment("guard known me");
- let ep_opnd = asm.load(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_EP));
+ let lep_opnd = gen_get_lep(jit, asm);
let ep_me_opnd = Opnd::mem(
64,
- ep_opnd,
+ lep_opnd,
SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_ME_CREF,
);
+
+ let me_as_value = VALUE(me as usize);
asm.cmp(ep_me_opnd, me_as_value.into());
asm.jne(counted_exit!(ocb, side_exit, invokesuper_me_changed));
@@ -6650,11 +6643,9 @@ fn gen_invokesuper(
// TODO: this could properly forward the current block handler, but
// would require changes to gen_send_*
asm.comment("guard no block given");
- // EP is in REG0 from above
- let ep_opnd = asm.load(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_EP));
let ep_specval_opnd = Opnd::mem(
64,
- ep_opnd,
+ lep_opnd,
SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL,
);
asm.cmp(ep_specval_opnd, VM_BLOCK_HANDLER_NONE.into());