Skip to content

Commit 73b4d19

Browse files
maximecbXrXr
authored andcommitted
Implement defined bytecode (#39)
1 parent f89037a commit 73b4d19

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

vm_insnhelper.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4188,6 +4188,12 @@ vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_
41884188
return false;
41894189
}
41904190

4191+
bool
4192+
rb_vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE obj, VALUE v)
4193+
{
4194+
return vm_defined(ec, reg_cfp, op_type, obj, v);
4195+
}
4196+
41914197
static const VALUE *
41924198
vm_get_ep(const VALUE *const reg_ep, rb_num_t lv)
41934199
{

yjit_codegen.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,51 @@ gen_setinstancevariable(jitstate_t* jit, ctx_t* ctx)
11741174
*/
11751175
}
11761176

1177+
bool rb_vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE obj, VALUE v);
1178+
1179+
static codegen_status_t
1180+
gen_defined(jitstate_t* jit, ctx_t* ctx)
1181+
{
1182+
rb_num_t op_type = (rb_num_t)jit_get_arg(jit, 0);
1183+
VALUE obj = (VALUE)jit_get_arg(jit, 1);
1184+
VALUE pushval = (VALUE)jit_get_arg(jit, 2);
1185+
1186+
// Save the PC and SP because the callee may allocate
1187+
// Note that this modifies REG_SP, which is why we do it first
1188+
jit_save_pc(jit, REG0);
1189+
jit_save_sp(jit, ctx);
1190+
1191+
// Get the operands from the stack
1192+
x86opnd_t v_opnd = ctx_stack_pop(ctx, 1);
1193+
1194+
// Call vm_defined(ec, reg_cfp, op_type, obj, v)
1195+
// Out of order because we're going to corrupt REG_SP and REG_CFP
1196+
yjit_save_regs(cb);
1197+
mov(cb, R9, REG_CFP);
1198+
mov(cb, C_ARG_REGS[0], REG_EC);
1199+
mov(cb, C_ARG_REGS[1], R9);
1200+
mov(cb, C_ARG_REGS[4], v_opnd); // depends on REG_SP
1201+
mov(cb, C_ARG_REGS[2], imm_opnd(op_type)); // clobers REG_SP
1202+
jit_mov_gc_ptr(jit, cb, C_ARG_REGS[3], (VALUE)obj);
1203+
call_ptr(cb, REG0, (void *)rb_vm_defined);
1204+
yjit_load_regs(cb);
1205+
1206+
// if (vm_defined(ec, GET_CFP(), op_type, obj, v)) {
1207+
// val = pushval;
1208+
// }
1209+
jit_mov_gc_ptr(jit, cb, REG1, (VALUE)pushval);
1210+
cmp(cb, AL, imm_opnd(0));
1211+
mov(cb, RAX, imm_opnd(Qnil));
1212+
cmovnz(cb, RAX, REG1);
1213+
1214+
// Push the return value onto the stack
1215+
val_type_t out_type = SPECIAL_CONST_P(pushval)? TYPE_IMM:TYPE_UNKNOWN;
1216+
x86opnd_t stack_ret = ctx_stack_push(ctx, out_type);
1217+
mov(cb, stack_ret, RAX);
1218+
1219+
return YJIT_KEEP_COMPILING;
1220+
}
1221+
11771222
static void
11781223
guard_two_fixnums(ctx_t* ctx, uint8_t* side_exit)
11791224
{
@@ -2673,6 +2718,7 @@ yjit_init_codegen(void)
26732718
yjit_reg_op(BIN(setlocal_WC_0), gen_setlocal_wc0);
26742719
yjit_reg_op(BIN(getinstancevariable), gen_getinstancevariable);
26752720
yjit_reg_op(BIN(setinstancevariable), gen_setinstancevariable);
2721+
yjit_reg_op(BIN(defined), gen_defined);
26762722
yjit_reg_op(BIN(opt_lt), gen_opt_lt);
26772723
yjit_reg_op(BIN(opt_le), gen_opt_le);
26782724
yjit_reg_op(BIN(opt_ge), gen_opt_ge);

0 commit comments

Comments
 (0)