diff options
-rw-r--r-- | bootstraptest/test_yjit.rb | 32 | ||||
-rw-r--r-- | yjit/src/codegen.rs | 19 |
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()); |