From 1ff14a855ab2389017a0de958702644233dbeb9f Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 10 Apr 2023 16:35:48 -0700 Subject: [PATCH] YJIT: Avoid using a register for unspecified_bits (#7685) Fix [Bug #19586] --- bootstraptest/test_yjit.rb | 19 +++++++++++++++++++ yjit/src/codegen.rs | 1 + 2 files changed, 20 insertions(+) diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index c2916908b2..34cb87ed88 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -3822,3 +3822,22 @@ assert_equal '[true, true, true, true]', %q{ assert_equal '0', %q{ 3[0, 0] } + +# unspecified_bits + checkkeyword +assert_equal '2', %q{ + def callee = 1 + + # checkkeyword should see unspecified_bits=0 (use bar), not Integer 1 (set bar = foo). + def foo(foo, bar: foo) = bar + + def entry(&block) + # write 1 at stack[3]. Calling #callee spills stack[3]. + 1 + (1 + (1 + (1 + callee))) + # &block is written to a register instead of stack[3]. When &block is popped and + # unspecified_bits is pushed, it must be written to stack[3], not to a register. + foo(1, bar: 2, &block) + end + + entry # call branch_stub_hit (spill temps) + entry # doesn't call branch_stub_hit (not spill temps) +} diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index e54b2e2752..e5e6cca563 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -6172,6 +6172,7 @@ fn gen_send_iseq( // pushed onto the stack that represents the parameters that weren't // explicitly given a value and have a non-constant default. let unspec_opnd = VALUE::fixnum_from_usize(unspecified_bits).as_u64(); + asm.spill_temps(ctx); // avoid using a register for unspecified_bits asm.mov(ctx.stack_opnd(-1), unspec_opnd.into()); }