diff options
-rw-r--r-- | bootstraptest/test_yjit.rb | 15 | ||||
-rw-r--r-- | yjit_asm.c | 5 | ||||
-rw-r--r-- | yjit_codegen.c | 6 |
3 files changed, 23 insertions, 3 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 2ac37df0a2..0b2b78ca4a 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -1,3 +1,18 @@ +assert_equal '18374962167983112447', %q{ + # regression test for incorrectly discarding 32 bits of a pointer when it + # comes to default values. + def large_literal_default(n: 0xff00_fabcafe0_00ff) + n + end + + def call_graph_root + large_literal_default + end + + call_graph_root + call_graph_root +} + assert_normal_exit %q{ # regression test for a leak caught by an asert on --yjit-call-threshold=2 Foo = 1 diff --git a/yjit_asm.c b/yjit_asm.c index 3a43c80ef0..64cbb163a2 100644 --- a/yjit_asm.c +++ b/yjit_asm.c @@ -1343,7 +1343,10 @@ void mov(codeblock_t *cb, x86opnd_t dst, x86opnd_t src) else cb_write_rm(cb, dst.num_bits == 16, dst.num_bits == 64, NO_OPND, dst, 0, 1, 0xC7); - cb_write_int(cb, src.as.imm, (dst.num_bits > 32)? 32:dst.num_bits); + const uint32_t output_num_bits = (dst.num_bits > 32u) ? 32u : dst.num_bits; + // assert that we can write whole immediate without loss of infomation + assert (sig_imm_size(src.as.imm) <= output_num_bits); + cb_write_int(cb, src.as.imm, output_num_bits); } else diff --git a/yjit_codegen.c b/yjit_codegen.c index 3378f1500d..38b830a097 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -3698,7 +3698,7 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r // This struct represents the metadata about the callee-specified // keyword parameters. - const struct rb_iseq_param_keyword *keyword = iseq->body->param.keyword; + const struct rb_iseq_param_keyword *const keyword = iseq->body->param.keyword; ADD_COMMENT(cb, "keyword args"); @@ -3748,7 +3748,9 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r default_value = Qnil; } - mov(cb, default_arg, imm_opnd(default_value)); + // GC might move default_value. + jit_mov_gc_ptr(jit, cb, REG0, default_value); + mov(cb, default_arg, REG0); caller_kwargs[kwarg_idx++] = callee_kwarg; } |