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

Fix local type tracking in getlocal, setlocal. Add test.

This commit is contained in:
Maxime Chevalier-Boisvert 2021-04-15 14:16:55 -04:00 committed by Alan Wu
parent 791f20af6e
commit edaf12def6
2 changed files with 35 additions and 38 deletions

View file

@ -89,6 +89,20 @@ assert_equal '0', %q{
retval = foo()
}
# Passing argument types to callees
assert_equal '8.5', %q{
def foo(x, y)
x + y
end
def bar
foo(7, 1.5)
end
bar
bar
}
# Recursive Ruby-to-Ruby calls
assert_equal '21', %q{
def fib(n)

View file

@ -257,13 +257,13 @@ yjit_entry_prologue(void)
return code_ptr;
}
// Generate code to check for interrupts and take a side-exit
static void
yjit_check_ints(codeblock_t* cb, uint8_t* side_exit)
{
// Check for interrupts
// see RUBY_VM_CHECK_INTS(ec) macro
ADD_COMMENT(cb, "RUBY_VM_CHECK_INTS(ec)");
mov(cb, REG0_32, member_opnd(REG_EC, rb_execution_context_t, interrupt_mask));
not(cb, REG0_32);
test(cb, member_opnd(REG_EC, rb_execution_context_t, interrupt_flag), REG0_32);
@ -289,7 +289,6 @@ jit_jump_to_next_insn(jitstate_t *jit, const ctx_t *current_context)
);
}
// Compile a sequence of bytecode instructions for a given basic block version
void
yjit_gen_block(ctx_t *ctx, block_t *block, rb_execution_context_t *ec)
@ -350,9 +349,9 @@ yjit_gen_block(ctx_t *ctx, block_t *block, rb_execution_context_t *ec)
break;
}
if (1) {
if (0) {
fprintf(stderr, "compiling %d: %s\n", insn_idx, insn_name(opcode));
//print_str(cb, insn_name(opcode));
print_str(cb, insn_name(opcode));
}
// :count-placement:
@ -518,41 +517,24 @@ gen_putself(jitstate_t* jit, ctx_t* ctx)
return YJIT_KEEP_COMPILING;
}
// Compute the index of a local variable from its slot index
uint32_t slot_to_local_idx(const rb_iseq_t *iseq, int32_t slot_idx)
{
// Convoluted rules from local_var_name() in iseq.c
int32_t local_table_size = iseq->body->local_table_size;
int32_t op = slot_idx - VM_ENV_DATA_SIZE;
int32_t local_idx = local_idx = local_table_size - op - 1;
RUBY_ASSERT(local_idx >= 0 && local_idx < local_table_size);
return (uint32_t)local_idx;
}
static codegen_status_t
gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx)
{
// Compute the offset from BP to the local
int32_t local_idx = (int32_t)jit_get_arg(jit, 0);
const int32_t offs = -(SIZEOF_VALUE * local_idx);
/*
if (local_idx < 8)
{
val_type_t local_type = ctx->local_types[local_idx];
if (local_type.type == ETYPE_FIXNUM) {
fprintf(stderr, "local_idx=%d is fixnum\n", local_idx);
ADD_COMMENT(cb, "local is fixnum");
}
else {
fprintf(stderr, "local_idx=%d not fixnum\n", local_idx);
ADD_COMMENT(cb, "local not fixnum");
}
}
else
{
fprintf(stderr, "local_idx=%d\n", local_idx);
}
*/
fprintf(stderr, "local_idx=%d\n", local_idx);
int32_t slot_idx = (int32_t)jit_get_arg(jit, 0);
const int32_t offs = -(SIZEOF_VALUE * slot_idx);
uint32_t local_idx = slot_to_local_idx(jit->iseq, slot_idx);
// Load environment pointer EP from CFP
mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep));
@ -610,7 +592,8 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx)
}
*/
int32_t local_idx = (int32_t)jit_get_arg(jit, 0);
int32_t slot_idx = (int32_t)jit_get_arg(jit, 0);
uint32_t local_idx = slot_to_local_idx(jit->iseq, slot_idx);
// Load environment pointer EP from CFP
mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep));
@ -634,7 +617,7 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx)
mov(cb, REG1, stack_top);
// Write the value at the environment pointer
const int32_t offs = -8 * local_idx;
const int32_t offs = -8 * slot_idx;
mov(cb, mem_opnd(64, REG0, offs), REG1);
return YJIT_KEEP_COMPILING;
@ -1728,7 +1711,7 @@ gen_oswb_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * -(argc + 1)));
mov(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), REG0);
// Store the next PC i the current frame
// Store the next PC in the current frame
mov(cb, REG0, const_ptr_opnd(jit->pc + insn_len(BIN(opt_send_without_block))));
mov(cb, mem_opnd(64, REG_CFP, offsetof(rb_control_frame_t, pc)), REG0);