@@ -1400,6 +1400,42 @@ gen_opt_aref(jitstate_t *jit, ctx_t *ctx)
1400
1400
}
1401
1401
}
1402
1402
1403
+ VALUE rb_vm_opt_aset (VALUE recv , VALUE obj , VALUE set );
1404
+
1405
+ static codegen_status_t
1406
+ gen_opt_aset (jitstate_t * jit , ctx_t * ctx )
1407
+ {
1408
+ // Save the PC and SP because the callee may allocate
1409
+ // Note that this modifies REG_SP, which is why we do it first
1410
+ jit_save_pc (jit , REG0 );
1411
+ jit_save_sp (jit , ctx );
1412
+
1413
+ uint8_t * side_exit = yjit_side_exit (jit , ctx );
1414
+
1415
+ // Get the operands from the stack
1416
+ x86opnd_t arg2 = ctx_stack_pop (ctx , 1 );
1417
+ x86opnd_t arg1 = ctx_stack_pop (ctx , 1 );
1418
+ x86opnd_t arg0 = ctx_stack_pop (ctx , 1 );
1419
+
1420
+ // Call rb_vm_opt_mod(VALUE recv, VALUE obj)
1421
+ yjit_save_regs (cb );
1422
+ mov (cb , C_ARG_REGS [0 ], arg0 );
1423
+ mov (cb , C_ARG_REGS [1 ], arg1 );
1424
+ mov (cb , C_ARG_REGS [2 ], arg2 );
1425
+ call_ptr (cb , REG0 , (void * )rb_vm_opt_aset );
1426
+ yjit_load_regs (cb );
1427
+
1428
+ // If val == Qundef, bail to do a method call
1429
+ cmp (cb , RAX , imm_opnd (Qundef ));
1430
+ je_ptr (cb , side_exit );
1431
+
1432
+ // Push the return value onto the stack
1433
+ x86opnd_t stack_ret = ctx_stack_push (ctx , TYPE_UNKNOWN );
1434
+ mov (cb , stack_ret , RAX );
1435
+
1436
+ return YJIT_KEEP_COMPILING ;
1437
+ }
1438
+
1403
1439
static codegen_status_t
1404
1440
gen_opt_and (jitstate_t * jit , ctx_t * ctx )
1405
1441
{
@@ -2532,6 +2568,7 @@ yjit_init_codegen(void)
2532
2568
yjit_reg_op (BIN (opt_gt ), gen_opt_gt );
2533
2569
yjit_reg_op (BIN (opt_eq ), gen_opt_eq );
2534
2570
yjit_reg_op (BIN (opt_aref ), gen_opt_aref );
2571
+ yjit_reg_op (BIN (opt_aset ), gen_opt_aset );
2535
2572
yjit_reg_op (BIN (opt_and ), gen_opt_and );
2536
2573
yjit_reg_op (BIN (opt_or ), gen_opt_or );
2537
2574
yjit_reg_op (BIN (opt_minus ), gen_opt_minus );
0 commit comments