summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hawthorn <john@hawthorn.email>2021-06-08 07:52:57 -0700
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:35 -0400
commit67c2cdc59a5fc8a82804c72a30a2d23ba36f2366 (patch)
tree902dab23e1a473a4d931419e9c151a676d01891e
parent5432f46f6a7a35a8d2a924eae7b1e29289a58292 (diff)
Implement gen_getlocal
This extracts the generation code from getlocal_wc1, since this is the same just with more loops inside vm_get_ep.
-rw-r--r--bootstraptest/test_yjit.rb14
-rw-r--r--yjit_codegen.c33
2 files changed, 38 insertions, 9 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 5bf415889e..51c82b55b5 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1021,3 +1021,17 @@ assert_equal 'foo123', %q{
make_str("foo", 123)
make_str("foo", 123)
}
+
+# getlocal with 2 levels
+assert_equal '7', %q{
+ def foo(foo, bar)
+ while foo > 0
+ while bar > 0
+ return foo + bar
+ end
+ end
+ end
+
+ foo(5,2)
+ foo(5,2)
+}
diff --git a/yjit_codegen.c b/yjit_codegen.c
index 87c5b12043..4870911404 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -787,22 +787,21 @@ gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx)
}
static codegen_status_t
-gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx)
+gen_getlocal_generic(ctx_t* ctx, uint32_t local_idx, uint32_t level)
{
- //fprintf(stderr, "gen_getlocal_wc1\n");
-
// Load environment pointer EP from CFP
mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep));
- // Get the previous EP from the current EP
- // See GET_PREV_EP(ep) macro
- // VALUE* prev_ep = ((VALUE *)((ep)[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03))
- mov(cb, REG0, mem_opnd(64, REG0, SIZEOF_VALUE * VM_ENV_DATA_INDEX_SPECVAL));
- and(cb, REG0, imm_opnd(~0x03));
+ while (level--) {
+ // Get the previous EP from the current EP
+ // See GET_PREV_EP(ep) macro
+ // VALUE* prev_ep = ((VALUE *)((ep)[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03))
+ mov(cb, REG0, mem_opnd(64, REG0, SIZEOF_VALUE * VM_ENV_DATA_INDEX_SPECVAL));
+ and(cb, REG0, imm_opnd(~0x03));
+ }
// Load the local from the block
// val = *(vm_get_ep(GET_EP(), level) - idx);
- int32_t local_idx = (int32_t)jit_get_arg(jit, 0);
const int32_t offs = -(SIZEOF_VALUE * local_idx);
mov(cb, REG0, mem_opnd(64, REG0, offs));
@@ -814,6 +813,21 @@ gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx)
}
static codegen_status_t
+gen_getlocal(jitstate_t* jit, ctx_t* ctx)
+{
+ int32_t idx = (int32_t)jit_get_arg(jit, 0);
+ int32_t level = (int32_t)jit_get_arg(jit, 1);
+ return gen_getlocal_generic(ctx, idx, level);
+}
+
+static codegen_status_t
+gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx)
+{
+ int32_t idx = (int32_t)jit_get_arg(jit, 0);
+ return gen_getlocal_generic(ctx, idx, 1);
+}
+
+static codegen_status_t
gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx)
{
/*
@@ -3067,6 +3081,7 @@ yjit_init_codegen(void)
yjit_reg_op(BIN(putobject_INT2FIX_0_), gen_putobject_int2fix);
yjit_reg_op(BIN(putobject_INT2FIX_1_), gen_putobject_int2fix);
yjit_reg_op(BIN(putself), gen_putself);
+ yjit_reg_op(BIN(getlocal), gen_getlocal);
yjit_reg_op(BIN(getlocal_WC_0), gen_getlocal_wc0);
yjit_reg_op(BIN(getlocal_WC_1), gen_getlocal_wc1);
yjit_reg_op(BIN(setlocal_WC_0), gen_setlocal_wc0);