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
}
# 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
assert_equal 'string', %q{
$foo = "string"
@ -18,6 +31,25 @@ assert_equal 'string', %q{
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
assert_equal 'true', %q{
def foo

View file

@ -149,7 +149,7 @@ jit_type_of_value(VALUE val)
// Save the incremented PC on the CFP
// This is necessary when calleees can raise or allocate
void
static void
jit_save_pc(jitstate_t* jit, x86opnd_t scratch_reg)
{
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
// Note: this will change the current value of REG_SP,
// which could invalidate memory operands
void
static void
jit_save_sp(jitstate_t* jit, ctx_t* ctx)
{
if (ctx->sp_offset != 0) {
@ -3431,6 +3431,10 @@ gen_getglobal(jitstate_t* jit, ctx_t* ctx)
{
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
yjit_save_regs(cb);
@ -3452,6 +3456,11 @@ gen_setglobal(jitstate_t* jit, ctx_t* ctx)
{
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
yjit_save_regs(cb);