diff options
| author | Stan Lo <stan.lo@shopify.com> | 2025-08-28 18:50:22 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-28 17:50:22 +0000 |
| commit | fa3c23eb811c7bee7c9ed945c8f12cb40ecd9b6a (patch) | |
| tree | 2265cd0170060f071aca0827bb0e15a1bb5d3b6d | |
| parent | b47ea34a9b9e602e70bb69478c4abd2d9f1651d0 (diff) | |
ZJIT: Prepare getglobal for non-leaf call (#14387)
Depending on the user's warning level, getting certain global variables
may lead to calling `Warning#warn`, which can be redefined by the user.
This fixes another `bootstraptest/test_yjit.rb` failure.
| -rw-r--r-- | test/ruby/test_zjit.rb | 21 | ||||
| -rw-r--r-- | zjit/src/codegen.rs | 7 |
2 files changed, 26 insertions, 2 deletions
diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb index e2a0120eb0..3ff1392ed7 100644 --- a/test/ruby/test_zjit.rb +++ b/test/ruby/test_zjit.rb @@ -78,6 +78,27 @@ class TestZJIT < Test::Unit::TestCase } end + def test_getglobal_with_warning + assert_compiles('"rescued"', %q{ + Warning[:deprecated] = true + + module Warning + def warn(message) + raise + end + end + + def test + $= + rescue + "rescued" + end + + $VERBOSE = true + test + }, insns: [:getglobal]) + end + def test_setglobal assert_compiles '1', %q{ def test diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 023498e3be..6c55b3fb5d 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -384,7 +384,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::CCall { cfun, args, name: _, return_type: _, elidable: _ } => gen_ccall(asm, *cfun, opnds!(args)), Insn::GetIvar { self_val, id, state: _ } => gen_getivar(asm, opnd!(self_val), *id), Insn::SetGlobal { id, val, state } => no_output!(gen_setglobal(jit, asm, *id, opnd!(val), &function.frame_state(*state))), - Insn::GetGlobal { id, state: _ } => gen_getglobal(asm, *id), + Insn::GetGlobal { id, state } => gen_getglobal(jit, asm, *id, &function.frame_state(*state)), &Insn::GetLocal { ep_offset, level } => gen_getlocal_with_ep(asm, ep_offset, level), &Insn::SetLocal { val, ep_offset, level } => no_output!(gen_setlocal_with_ep(asm, opnd!(val), function.type_of(val), ep_offset, level)), Insn::GetConstantPath { ic, state } => gen_get_constant_path(jit, asm, *ic, &function.frame_state(*state)), @@ -609,7 +609,10 @@ fn gen_setivar(asm: &mut Assembler, recv: Opnd, id: ID, val: Opnd) { } /// Look up global variables -fn gen_getglobal(asm: &mut Assembler, id: ID) -> Opnd { +fn gen_getglobal(jit: &mut JITState, asm: &mut Assembler, id: ID, state: &FrameState) -> Opnd { + // `Warning` module's method `warn` can be called when reading certain global variables + gen_prepare_non_leaf_call(jit, asm, state); + asm_ccall!(asm, rb_gvar_get, id.0.into()) } |
