1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Save PC and SP before accessing globals

These instructions are marked as not leaf in insns.def, which indicate
that they could raise exceptions and/or call Ruby methods.
This commit is contained in:
Alan Wu 2021-07-29 12:41:59 -04:00
parent b91078ea74
commit f4f940e5a6
2 changed files with 43 additions and 2 deletions

View file

@ -7,6 +7,19 @@ assert_equal 'string', %q{
foo foo
} }
# Check that exceptions work when setting global variables
assert_equal 'rescued', %q{
def set_var
$var = 100
rescue
:rescued
end
set_var
trace_var(:$var) { raise }
set_var
}
# Check that global variables work # Check that global variables work
assert_equal 'string', %q{ assert_equal 'string', %q{
$foo = "string" $foo = "string"
@ -18,6 +31,25 @@ assert_equal 'string', %q{
foo foo
} }
# Check that exceptions work when getting global variable
assert_equal 'rescued', %q{
module Warning
def warn(message)
raise
end
end
def get_var
$=
rescue
:rescued
end
$VERBOSE = true
get_var
get_var
}
# Check that global tracepoints work # Check that global tracepoints work
assert_equal 'true', %q{ assert_equal 'true', %q{
def foo def foo

View file

@ -149,7 +149,7 @@ jit_type_of_value(VALUE val)
// Save the incremented PC on the CFP // Save the incremented PC on the CFP
// This is necessary when calleees can raise or allocate // This is necessary when calleees can raise or allocate
void static void
jit_save_pc(jitstate_t* jit, x86opnd_t scratch_reg) jit_save_pc(jitstate_t* jit, x86opnd_t scratch_reg)
{ {
mov(cb, scratch_reg, const_ptr_opnd(jit->pc + insn_len(jit->opcode))); mov(cb, scratch_reg, const_ptr_opnd(jit->pc + insn_len(jit->opcode)));
@ -160,7 +160,7 @@ jit_save_pc(jitstate_t* jit, x86opnd_t scratch_reg)
// This realigns the interpreter SP with the JIT SP // This realigns the interpreter SP with the JIT SP
// Note: this will change the current value of REG_SP, // Note: this will change the current value of REG_SP,
// which could invalidate memory operands // which could invalidate memory operands
void static void
jit_save_sp(jitstate_t* jit, ctx_t* ctx) jit_save_sp(jitstate_t* jit, ctx_t* ctx)
{ {
if (ctx->sp_offset != 0) { if (ctx->sp_offset != 0) {
@ -3431,6 +3431,10 @@ gen_getglobal(jitstate_t* jit, ctx_t* ctx)
{ {
ID gid = jit_get_arg(jit, 0); ID gid = jit_get_arg(jit, 0);
// Save the PC and SP because we might make a Ruby call for warning
jit_save_pc(jit, REG0);
jit_save_sp(jit, ctx);
// Save YJIT registers // Save YJIT registers
yjit_save_regs(cb); yjit_save_regs(cb);
@ -3452,6 +3456,11 @@ gen_setglobal(jitstate_t* jit, ctx_t* ctx)
{ {
ID gid = jit_get_arg(jit, 0); ID gid = jit_get_arg(jit, 0);
// Save the PC and SP because we might make a Ruby call for
// Kernel#set_trace_var
jit_save_pc(jit, REG0);
jit_save_sp(jit, ctx);
// Save YJIT registers // Save YJIT registers
yjit_save_regs(cb); yjit_save_regs(cb);