aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--yjit/src/codegen.rs21
1 files changed, 13 insertions, 8 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index bfac557a4c..b6aa75953e 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -5147,12 +5147,6 @@ fn gen_send_iseq(
let opt_num = unsafe { get_iseq_body_param_opt_num(iseq) };
let opts_missing: i32 = opt_num - opts_filled;
-
- if opt_num > 0 && flags & VM_CALL_ARGS_SPLAT != 0 {
- gen_counter_incr!(asm, send_iseq_splat_with_opt);
- return CantCompile;
- }
-
if doing_kw_call && flags & VM_CALL_ARGS_SPLAT != 0 {
gen_counter_incr!(asm, send_iseq_splat_with_kw);
return CantCompile;
@@ -5198,13 +5192,24 @@ fn gen_send_iseq(
return CantCompile;
}
- if opt_num > 0 {
+ if opt_num > 0 && flags & VM_CALL_ARGS_SPLAT == 0 {
num_params -= opts_missing as u32;
unsafe {
let opt_table = get_iseq_body_param_opt_table(iseq);
start_pc_offset = (*opt_table.offset(opts_filled as isize)).as_u32();
}
- }
+ } else if opt_num > 0 && flags & VM_CALL_ARGS_SPLAT != 0 {
+ // We are going to assume that args_splat fills all of the optional arguments.
+ // We should actually get the array length instead at compile time.
+ // We don't set num_params here because we use it for the splat.
+ // If our assumption is wrong, we will exit early in the splat code.
+ // We could do that a bit smarter and not exit but instead change
+ // the offset we jump to. But we aren't currently doing that.
+ unsafe {
+ let opt_table = get_iseq_body_param_opt_table(iseq);
+ start_pc_offset = (*opt_table.offset(opt_num as isize)).as_u32();
+ };
+ };
if doing_kw_call {
// Here we're calling a method with keyword arguments and specifying