@@ -4217,7 +4217,7 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
42174217 return CantCompile
42184218 end
42194219
4220- # block_arg = flags & C::VM_CALL_ARGS_BLOCKARG != 0
4220+ block_arg = flags & C ::VM_CALL_ARGS_BLOCKARG != 0
42214221 # jit_caller_setup_arg_block already handled send_blockarg_not_nil_or_proxy
42224222
42234223 # If we have unfilled optional arguments and keyword arguments then we
@@ -4318,9 +4318,17 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
43184318 end
43194319 end
43204320 if flags & C ::VM_CALL_ARGS_SPLAT != 0 && !iseq_has_rest
4321- splat_array_length = false
4322- asm . incr_counter ( :send_iseq_splat )
4323- return CantCompile
4321+ array = jit . peek_at_stack ( block_arg ? 1 : 0 )
4322+ splat_array_length = if array . nil?
4323+ 0
4324+ else
4325+ array . length
4326+ end
4327+
4328+ if opt_num == 0 && required_num != splat_array_length + argc - 1
4329+ asm . incr_counter ( :send_iseq_splat_arity_error )
4330+ return CantCompile
4331+ end
43244332 end
43254333
43264334 # We will not have CantCompile from here.
@@ -4350,8 +4358,25 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
43504358
43514359 # push_splat_args does stack manipulation so we can no longer side exit
43524360 if splat_array_length
4353- asm . incr_counter ( :send_iseq_splat )
4354- return CantCompile
4361+ remaining_opt = ( opt_num + required_num ) - ( splat_array_length + ( argc - 1 ) )
4362+
4363+ if opt_num > 0
4364+ # We are going to jump to the correct offset based on how many optional
4365+ # params are remaining.
4366+ offset = opt_num - remaining_opt
4367+ start_pc_offset = iseq . body . param . opt_table [ offset ]
4368+ end
4369+ # We are going to assume that the splat fills
4370+ # all the remaining arguments. In the generated code
4371+ # we test if this is true and if not side exit.
4372+ argc = argc - 1 + splat_array_length + remaining_opt
4373+ push_splat_args ( splat_array_length , jit , ctx , asm )
4374+
4375+ remaining_opt . times do
4376+ # We need to push nil for the optional arguments
4377+ stack_ret = ctx . stack_push
4378+ asm . mov ( stack_ret , Qnil )
4379+ end
43554380 end
43564381
43574382 # This is a .send call and we need to adjust the stack
@@ -4730,7 +4755,7 @@ def jit_call_cfunc_with_frame(jit, ctx, asm, cme, flags, argc, block_handler, kn
47304755 # So the number of args should just equal the number of args the cfunc takes.
47314756 # In the generated code we test if this is true and if not side exit.
47324757 argc = cfunc . argc
4733- jit_caller_setup_arg_splat ( jit , ctx , asm , required_args )
4758+ push_splat_args ( required_args , jit , ctx , asm )
47344759 end
47354760
47364761 # We will not have side exits from here. Adjust the stack, which was skipped in jit_call_opt_send.
@@ -5344,7 +5369,7 @@ def move_rest_args_to_stack(array, num_args, jit, ctx, asm)
53445369 # @param jit [RubyVM::RJIT::JITState]
53455370 # @param ctx [RubyVM::RJIT::Context]
53465371 # @param asm [RubyVM::RJIT::Assembler]
5347- def jit_caller_setup_arg_splat ( jit , ctx , asm , required_args )
5372+ def push_splat_args ( required_args , jit , ctx , asm )
53485373 side_exit = side_exit ( jit , ctx )
53495374
53505375 asm . comment ( 'push_splat_args' )
0 commit comments