@@ -1067,8 +1067,14 @@ gen_oswb_cfunc(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb_c
1067
1067
{
1068
1068
const rb_method_cfunc_t * cfunc = UNALIGNED_MEMBER_PTR (cme -> def , body .cfunc );
1069
1069
1070
- // Don't JIT if the argument count doesn't match
1071
- if (cfunc -> argc < 0 || cfunc -> argc != argc )
1070
+ // If the function expects a Ruby array of arguments
1071
+ if (cfunc -> argc < 0 && cfunc -> argc != -1 )
1072
+ {
1073
+ return false;
1074
+ }
1075
+
1076
+ // If the argument count doesn't match
1077
+ if (cfunc -> argc >= 0 && cfunc -> argc != argc )
1072
1078
{
1073
1079
return false;
1074
1080
}
@@ -1201,13 +1207,26 @@ gen_oswb_cfunc(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb_c
1201
1207
// Copy SP into RAX because REG_SP will get overwritten
1202
1208
lea (cb , RAX , ctx_sp_opnd (ctx , 0 ));
1203
1209
1204
- // Copy the arguments from the stack to the C argument registers
1205
- // self is the 0th argument and is at index argc from the stack top
1206
- for (int32_t i = 0 ; i < argc + 1 ; ++ i )
1210
+ // Non-variadic method
1211
+ if (cfunc -> argc >= 0 )
1212
+ {
1213
+ // Copy the arguments from the stack to the C argument registers
1214
+ // self is the 0th argument and is at index argc from the stack top
1215
+ for (int32_t i = 0 ; i < argc + 1 ; ++ i )
1216
+ {
1217
+ x86opnd_t stack_opnd = mem_opnd (64 , RAX , - (argc + 1 - i ) * SIZEOF_VALUE );
1218
+ x86opnd_t c_arg_reg = C_ARG_REGS [i ];
1219
+ mov (cb , c_arg_reg , stack_opnd );
1220
+ }
1221
+ }
1222
+ // Variadic method
1223
+ if (cfunc -> argc == -1 )
1207
1224
{
1208
- x86opnd_t stack_opnd = mem_opnd (64 , RAX , - (argc + 1 - i ) * 8 );
1209
- x86opnd_t c_arg_reg = C_ARG_REGS [i ];
1210
- mov (cb , c_arg_reg , stack_opnd );
1225
+ // The method gets a pointer to the first argument
1226
+ // rb_f_puts(int argc, VALUE *argv, VALUE recv)
1227
+ mov (cb , C_ARG_REGS [0 ], imm_opnd (argc ));
1228
+ lea (cb , C_ARG_REGS [1 ], mem_opnd (64 , RAX , - (argc ) * SIZEOF_VALUE ));
1229
+ mov (cb , C_ARG_REGS [2 ], mem_opnd (64 , RAX , - (argc + 1 ) * SIZEOF_VALUE ));
1211
1230
}
1212
1231
1213
1232
// Pop the C function arguments from the stack (in the caller)
0 commit comments