Skip to content

Commit f300ab6

Browse files
author
Maxime Chevalier-Boisvert
committed
Fix local type tracking in getlocal, setlocal. Add test.
1 parent ca80199 commit f300ab6

2 files changed

Lines changed: 35 additions & 38 deletions

File tree

bootstraptest/test_yjit.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,20 @@ def foo
8989
retval = foo()
9090
}
9191

92+
# Passing argument types to callees
93+
assert_equal '8.5', %q{
94+
def foo(x, y)
95+
x + y
96+
end
97+
98+
def bar
99+
foo(7, 1.5)
100+
end
101+
102+
bar
103+
bar
104+
}
105+
92106
# Recursive Ruby-to-Ruby calls
93107
assert_equal '21', %q{
94108
def fib(n)

yjit_codegen.c

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,13 @@ yjit_entry_prologue(void)
254254
return code_ptr;
255255
}
256256

257-
258257
// Generate code to check for interrupts and take a side-exit
259258
static void
260259
yjit_check_ints(codeblock_t* cb, uint8_t* side_exit)
261260
{
262261
// Check for interrupts
263262
// see RUBY_VM_CHECK_INTS(ec) macro
263+
ADD_COMMENT(cb, "RUBY_VM_CHECK_INTS(ec)");
264264
mov(cb, REG0_32, member_opnd(REG_EC, rb_execution_context_t, interrupt_mask));
265265
not(cb, REG0_32);
266266
test(cb, member_opnd(REG_EC, rb_execution_context_t, interrupt_flag), REG0_32);
@@ -286,7 +286,6 @@ jit_jump_to_next_insn(jitstate_t *jit, const ctx_t *current_context)
286286
);
287287
}
288288

289-
290289
// Compile a sequence of bytecode instructions for a given basic block version
291290
void
292291
yjit_gen_block(ctx_t *ctx, block_t *block, rb_execution_context_t *ec)
@@ -348,9 +347,9 @@ yjit_gen_block(ctx_t *ctx, block_t *block, rb_execution_context_t *ec)
348347
break;
349348
}
350349

351-
if (1) {
350+
if (0) {
352351
fprintf(stderr, "compiling %d: %s\n", insn_idx, insn_name(opcode));
353-
//print_str(cb, insn_name(opcode));
352+
print_str(cb, insn_name(opcode));
354353
}
355354

356355
// :count-placement:
@@ -512,41 +511,24 @@ gen_putself(jitstate_t* jit, ctx_t* ctx)
512511
return YJIT_KEEP_COMPILING;
513512
}
514513

514+
// Compute the index of a local variable from its slot index
515+
uint32_t slot_to_local_idx(const rb_iseq_t *iseq, int32_t slot_idx)
516+
{
517+
// Convoluted rules from local_var_name() in iseq.c
518+
int32_t local_table_size = iseq->body->local_table_size;
519+
int32_t op = slot_idx - VM_ENV_DATA_SIZE;
520+
int32_t local_idx = local_idx = local_table_size - op - 1;
521+
RUBY_ASSERT(local_idx >= 0 && local_idx < local_table_size);
522+
return (uint32_t)local_idx;
523+
}
524+
515525
static codegen_status_t
516526
gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx)
517527
{
518528
// Compute the offset from BP to the local
519-
int32_t local_idx = (int32_t)jit_get_arg(jit, 0);
520-
const int32_t offs = -(SIZEOF_VALUE * local_idx);
521-
522-
523-
524-
/*
525-
if (local_idx < 8)
526-
{
527-
val_type_t local_type = ctx->local_types[local_idx];
528-
529-
if (local_type.type == ETYPE_FIXNUM) {
530-
fprintf(stderr, "local_idx=%d is fixnum\n", local_idx);
531-
ADD_COMMENT(cb, "local is fixnum");
532-
}
533-
else {
534-
fprintf(stderr, "local_idx=%d not fixnum\n", local_idx);
535-
ADD_COMMENT(cb, "local not fixnum");
536-
}
537-
}
538-
else
539-
{
540-
fprintf(stderr, "local_idx=%d\n", local_idx);
541-
}
542-
*/
543-
544-
545-
fprintf(stderr, "local_idx=%d\n", local_idx);
546-
547-
548-
549-
529+
int32_t slot_idx = (int32_t)jit_get_arg(jit, 0);
530+
const int32_t offs = -(SIZEOF_VALUE * slot_idx);
531+
uint32_t local_idx = slot_to_local_idx(jit->iseq, slot_idx);
550532

551533
// Load environment pointer EP from CFP
552534
mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep));
@@ -604,7 +586,8 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx)
604586
}
605587
*/
606588

607-
int32_t local_idx = (int32_t)jit_get_arg(jit, 0);
589+
int32_t slot_idx = (int32_t)jit_get_arg(jit, 0);
590+
uint32_t local_idx = slot_to_local_idx(jit->iseq, slot_idx);
608591

609592
// Load environment pointer EP from CFP
610593
mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep));
@@ -628,7 +611,7 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx)
628611
mov(cb, REG1, stack_top);
629612

630613
// Write the value at the environment pointer
631-
const int32_t offs = -8 * local_idx;
614+
const int32_t offs = -8 * slot_idx;
632615
mov(cb, mem_opnd(64, REG0, offs), REG1);
633616

634617
return YJIT_KEEP_COMPILING;
@@ -1704,7 +1687,7 @@ gen_oswb_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
17041687
lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * -(argc + 1)));
17051688
mov(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), REG0);
17061689

1707-
// Store the next PC i the current frame
1690+
// Store the next PC in the current frame
17081691
mov(cb, REG0, const_ptr_opnd(jit->pc + insn_len(BIN(opt_send_without_block))));
17091692
mov(cb, mem_opnd(64, REG_CFP, offsetof(rb_control_frame_t, pc)), REG0);
17101693

0 commit comments

Comments
 (0)