ZJIT: Prepare non-leaf calls for SetGlobal (#14197)
Some checks failed
Cygwin / make (push) Waiting to run
MinGW / (UCRT64) (push) Waiting to run
Windows / Windows 11-arm/Visual C++ (btest test-basic test-tool) (push) Waiting to run
Windows / Windows 2022/Visual C++ 2022 (check) (push) Waiting to run
Windows / Windows 2025/Visual C++ 2022 (check) (push) Waiting to run
Windows / Windows 2025/Visual C++ 2022 (test-bundled-gems) (push) Waiting to run
Windows / result (push) Blocked by required conditions
Ubuntu on WSL / wsl (push) Waiting to run
Annocheck / test-annocheck (push) Failing after 59s
Check Dependencies / Dependency checks (push) Failing after 56s
Misc / Miscellaneous checks (push) Failing after 1m4s
CodeQL / Analyze (push) Failing after 56s
Compilations / omnibus compilations, trigger (push) Failing after 52s
Update default gems list / Update default gems list (push) Has been skipped
parse.y / make (check) (push) Failing after 56s
parse.y / make (test-bundled-gems) (push) Failing after 56s
parse.y / make (test-bundler-parallel) (push) Failing after 57s
WebAssembly / make (map[debugflags: name:O2 optflags:-O2 wasmoptflags:-O2]) (push) Failing after 1m1s
Compilations / omnibus compilations, #5 (push) Has been skipped
Compilations / omnibus compilations, #6 (push) Has been skipped
Compilations / omnibus compilations, #8 (push) Has been skipped
Compilations / omnibus compilations, #10 (push) Has been skipped
Compilations / omnibus compilations, #11 (push) Has been skipped
BASERUBY Check / BASERUBY (push) Failing after 52s
Compilations / omnibus compilations, #1 (push) Has been skipped
Compilations / omnibus compilations, #2 (push) Has been skipped
Compilations / omnibus compilations, #3 (push) Has been skipped
Compilations / omnibus compilations, #4 (push) Has been skipped
Compilations / omnibus compilations, #7 (push) Has been skipped
Compilations / omnibus compilations, #9 (push) Has been skipped
Compilations / omnibus compilations, #12 (push) Has been skipped
Compilations / omnibus compilations, result (push) Successful in 1m14s

When trace_var is used, setting a global variable can cause exceptions
to be raised. We need to prepare for that.
This commit is contained in:
Stan Lo 2025-08-13 01:39:46 +01:00 committed by GitHub
parent 1afc07e815
commit df7d9812cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 2 deletions

View file

@ -61,6 +61,30 @@ class TestZJIT < Test::Unit::TestCase
} }
end end
def test_setglobal
assert_compiles '1', %q{
def test
$a = 1
$a
end
test
}, insns: [:setglobal]
end
def test_setglobal_with_trace_var_exception
assert_compiles '"rescued"', %q{
def test
$a = 1
rescue
"rescued"
end
trace_var(:$a) { raise }
test
}, insns: [:setglobal]
end
def test_setlocal def test_setlocal
assert_compiles '3', %q{ assert_compiles '3', %q{
def test(n) def test(n)

View file

@ -367,7 +367,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
Insn::PatchPoint { invariant, state } => return gen_patch_point(jit, asm, invariant, &function.frame_state(*state)), Insn::PatchPoint { invariant, state } => return gen_patch_point(jit, asm, invariant, &function.frame_state(*state)),
Insn::CCall { cfun, args, name: _, return_type: _, elidable: _ } => gen_ccall(asm, *cfun, opnds!(args))?, 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::GetIvar { self_val, id, state: _ } => gen_getivar(asm, opnd!(self_val), *id),
Insn::SetGlobal { id, val, state: _ } => return Some(gen_setglobal(asm, *id, opnd!(val))), Insn::SetGlobal { id, val, state } => return 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(asm, *id),
&Insn::GetLocal { ep_offset, level } => gen_getlocal_with_ep(asm, ep_offset, level)?, &Insn::GetLocal { ep_offset, level } => gen_getlocal_with_ep(asm, ep_offset, level)?,
Insn::SetLocal { val, ep_offset, level } => return gen_setlocal_with_ep(asm, opnd!(val), *ep_offset, *level), Insn::SetLocal { val, ep_offset, level } => return gen_setlocal_with_ep(asm, opnd!(val), *ep_offset, *level),
@ -592,8 +592,12 @@ fn gen_getglobal(asm: &mut Assembler, id: ID) -> Opnd {
} }
/// Set global variables /// Set global variables
fn gen_setglobal(asm: &mut Assembler, id: ID, val: Opnd) { fn gen_setglobal(jit: &mut JITState, asm: &mut Assembler, id: ID, val: Opnd, state: &FrameState) -> Option<()> {
// When trace_var is used, setting a global variable can cause exceptions
gen_prepare_non_leaf_call(jit, asm, state)?;
asm_ccall!(asm, rb_gvar_set, id.0.into(), val); asm_ccall!(asm, rb_gvar_set, id.0.into(), val);
Some(())
} }
/// Side-exit into the interpreter /// Side-exit into the interpreter