@@ -1174,6 +1174,51 @@ gen_setinstancevariable(jitstate_t* jit, ctx_t* ctx)
1174
1174
*/
1175
1175
}
1176
1176
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
+
1177
1222
static void
1178
1223
guard_two_fixnums (ctx_t * ctx , uint8_t * side_exit )
1179
1224
{
@@ -2673,6 +2718,7 @@ yjit_init_codegen(void)
2673
2718
yjit_reg_op (BIN (setlocal_WC_0 ), gen_setlocal_wc0 );
2674
2719
yjit_reg_op (BIN (getinstancevariable ), gen_getinstancevariable );
2675
2720
yjit_reg_op (BIN (setinstancevariable ), gen_setinstancevariable );
2721
+ yjit_reg_op (BIN (defined ), gen_defined );
2676
2722
yjit_reg_op (BIN (opt_lt ), gen_opt_lt );
2677
2723
yjit_reg_op (BIN (opt_le ), gen_opt_le );
2678
2724
yjit_reg_op (BIN (opt_ge ), gen_opt_ge );
0 commit comments