@@ -1559,15 +1559,7 @@ def invokeblock(jit, ctx, asm)
15591559 block_changed_exit = counted_exit ( side_exit , :invokeblock_iseq_block_changed )
15601560 jit_chain_guard ( :jne , jit , ctx , asm , block_changed_exit )
15611561
1562- opt_pc = jit_callee_setup_block_arg ( jit , ctx , asm , calling , comptime_iseq , arg_setup_type : :arg_setup_block )
1563- if opt_pc == CantCompile
1564- return CantCompile
1565- end
1566-
1567- jit_call_iseq_setup_normal (
1568- jit , ctx , asm , nil , calling , comptime_iseq , opt_pc ,
1569- frame_type : C ::VM_FRAME_MAGIC_BLOCK ,
1570- )
1562+ jit_call_iseq ( jit , ctx , asm , nil , calling , comptime_iseq , frame_type : C ::VM_FRAME_MAGIC_BLOCK )
15711563 elsif comptime_handler & 0x3 == 0x3 # VM_BH_IFUNC_P
15721564 # We aren't handling CALLER_SETUP_ARG and CALLER_REMOVE_EMPTY_KW_SPLAT yet.
15731565 if calling . flags & C ::VM_CALL_ARGS_SPLAT != 0
@@ -4309,68 +4301,6 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
43094301 EndBlock
43104302 end
43114303
4312- # vm_call_iseq_setup_normal (vm_call_iseq_setup_2 -> vm_call_iseq_setup_normal)
4313- # @param jit [RubyVM::RJIT::JITState]
4314- # @param ctx [RubyVM::RJIT::Context]
4315- # @param asm [RubyVM::RJIT::Assembler]
4316- def jit_call_iseq_setup_normal ( jit , ctx , asm , cme , calling , iseq , opt_pc , frame_type :, prev_ep : nil )
4317- argc = calling . argc
4318- flags = calling . flags
4319- send_shift = calling . send_shift
4320- block_handler = calling . block_handler
4321-
4322- # Push splat args, which was skipped in jit_caller_setup_arg.
4323- if flags & C ::VM_CALL_ARGS_SPLAT != 0
4324- lead_num = iseq . body . param . lead_num
4325- opt_num = iseq . body . param . opt_num
4326-
4327- array_length = jit . peek_at_stack ( flags & C ::VM_CALL_ARGS_BLOCKARG != 0 ? 1 : 0 ) &.length || 0 # blockarg is not popped yet
4328- if opt_num == 0 && lead_num != array_length + argc - 1
4329- asm . incr_counter ( :send_args_splat_arity_error )
4330- return CantCompile
4331- end
4332-
4333- remaining_opt = ( opt_num + lead_num ) - ( array_length + argc - 1 )
4334- if opt_num > 0
4335- # We are going to jump to the correct offset based on how many optional params are remaining.
4336- opt_pc = iseq . body . param . opt_table [ opt_num - remaining_opt ]
4337- end
4338-
4339- # We are going to assume that the splat fills all the remaining arguments.
4340- # In the generated code we test if this is true and if not side exit.
4341- argc = argc - 1 + array_length
4342- jit_caller_setup_arg_splat ( jit , ctx , asm , array_length )
4343- end
4344-
4345- # We will not have side exits from here. Adjust the stack, which was skipped in jit_call_opt_send.
4346- if flags & C ::VM_CALL_OPT_SEND != 0
4347- jit_call_opt_send_shift_stack ( ctx , asm , argc , send_shift :)
4348- end
4349-
4350- if block_handler == C ::VM_BLOCK_HANDLER_NONE && iseq . body . builtin_attrs & C ::BUILTIN_ATTR_LEAF != 0
4351- if jit_leaf_builtin_func ( jit , ctx , asm , flags , iseq )
4352- return KeepCompiling
4353- end
4354- end
4355-
4356- frame_type ||= C ::VM_FRAME_MAGIC_METHOD | C ::VM_ENV_FLAG_LOCAL
4357- jit_push_frame (
4358- jit , ctx , asm , cme , flags , argc , frame_type , block_handler ,
4359- iseq : iseq ,
4360- local_size : iseq . body . local_table_size - iseq . body . param . size ,
4361- stack_max : iseq . body . stack_max ,
4362- prev_ep :,
4363- push_opts : true ,
4364- )
4365-
4366- # Jump to a stub for the callee ISEQ
4367- callee_ctx = Context . new
4368- pc = ( iseq . body . iseq_encoded + opt_pc ) . to_i
4369- jit_direct_jump ( iseq , pc , callee_ctx , asm )
4370-
4371- EndBlock
4372- end
4373-
43744304 def jit_leaf_builtin_func ( jit , ctx , asm , flags , iseq )
43754305 builtin_func = builtin_function ( iseq )
43764306 if builtin_func . nil?
@@ -4728,7 +4658,7 @@ def jit_call_opt_send(jit, ctx, asm, cme, calling, known_recv_class)
47284658 asm . incr_counter ( :send_optimized_send_send )
47294659 return CantCompile
47304660 end
4731- # Lazily handle stack shift in jit_call_iseq_setup_normal
4661+ # Lazily handle stack shift in jit_call_opt_send_shift_stack
47324662 calling . send_shift += 1
47334663
47344664 jit_call_symbol ( jit , ctx , asm , cme , calling , known_recv_class , C ::VM_CALL_FCALL )
@@ -4904,7 +4834,7 @@ def jit_call_symbol(jit, ctx, asm, cme, calling, known_recv_class, flags)
49044834 # @param jit [RubyVM::RJIT::JITState]
49054835 # @param ctx [RubyVM::RJIT::Context]
49064836 # @param asm [RubyVM::RJIT::Assembler]
4907- def jit_push_frame ( jit , ctx , asm , cme , flags , argc , frame_type , block_handler , iseq : nil , local_size : 0 , stack_max : 0 , prev_ep : nil , push_opts : false )
4837+ def jit_push_frame ( jit , ctx , asm , cme , flags , argc , frame_type , block_handler , iseq : nil , local_size : 0 , stack_max : 0 , prev_ep : nil )
49084838 # CHECK_VM_STACK_OVERFLOW0: next_cfp <= sp + (local_size + stack_max)
49094839 asm . comment ( 'stack overflow check' )
49104840 asm . lea ( :rax , ctx . sp_opnd ( C . rb_control_frame_t . size + C . VALUE . size * ( local_size + stack_max ) ) )
@@ -4932,12 +4862,6 @@ def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, i
49324862 ctx . stack_pop ( 1 )
49334863 end
49344864
4935- if iseq && push_opts
4936- # This was not handled in jit_callee_setup_arg
4937- opts_filled = argc - iseq . body . param . lead_num # TODO: kwarg
4938- opts_missing = iseq . body . param . opt_num - opts_filled
4939- local_size += opts_missing
4940- end
49414865 local_size . times do |i |
49424866 asm . comment ( 'set local variables' ) if i == 0
49434867 local_index = ctx . sp_offset + i
@@ -5041,198 +4965,6 @@ def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, i
50414965 asm . mov ( [ EC , C . rb_execution_context_t . offsetof ( :cfp ) ] , cfp_reg )
50424966 end
50434967
5044- # vm_callee_setup_arg (ISEQ only): Set up args and return opt_pc (or CantCompile)
5045- # @param jit [RubyVM::RJIT::JITState]
5046- # @param ctx [RubyVM::RJIT::Context]
5047- # @param asm [RubyVM::RJIT::Assembler]
5048- def jit_callee_setup_arg ( jit , ctx , asm , flags , argc , iseq )
5049- if flags & C ::VM_CALL_KW_SPLAT == 0
5050- if C . rb_simple_iseq_p ( iseq )
5051- if jit_caller_setup_arg ( jit , ctx , asm , flags , splat : true ) == CantCompile
5052- return CantCompile
5053- end
5054- if jit_caller_remove_empty_kw_splat ( jit , ctx , asm , flags ) == CantCompile
5055- return CantCompile
5056- end
5057-
5058- if argc != iseq . body . param . lead_num
5059- # argument_arity_error
5060- return CantCompile
5061- end
5062-
5063- return 0
5064- elsif C . rb_iseq_only_optparam_p ( iseq )
5065- if jit_caller_setup_arg ( jit , ctx , asm , flags , splat : true ) == CantCompile
5066- return CantCompile
5067- end
5068- if jit_caller_remove_empty_kw_splat ( jit , ctx , asm , flags ) == CantCompile
5069- return CantCompile
5070- end
5071-
5072- lead_num = iseq . body . param . lead_num
5073- opt_num = iseq . body . param . opt_num
5074- opt = argc - lead_num
5075-
5076- if opt < 0 || opt > opt_num
5077- asm . incr_counter ( :send_arity )
5078- return CantCompile
5079- end
5080-
5081- # Qnil push is handled in jit_push_frame
5082-
5083- return iseq . body . param . opt_table [ opt ]
5084- elsif C . rb_iseq_only_kwparam_p ( iseq ) && ( flags & C ::VM_CALL_ARGS_SPLAT ) == 0
5085- asm . incr_counter ( :send_iseq_kwparam )
5086- return CantCompile
5087- end
5088- end
5089-
5090- return jit_setup_parameters_complex ( jit , ctx , asm , flags , argc , iseq )
5091- end
5092-
5093- # vm_callee_setup_block_arg (ISEQ only): Set up args and return opt_pc (or CantCompile)
5094- # @param jit [RubyVM::RJIT::JITState]
5095- # @param ctx [RubyVM::RJIT::Context]
5096- # @param asm [RubyVM::RJIT::Assembler]
5097- def jit_callee_setup_block_arg ( jit , ctx , asm , calling , iseq , arg_setup_type :)
5098- if C . rb_simple_iseq_p ( iseq )
5099- if jit_caller_setup_arg ( jit , ctx , asm , calling . flags , splat : true ) == CantCompile
5100- return CantCompile
5101- end
5102-
5103- if arg_setup_type == :arg_setup_block &&
5104- calling . argc == 1 &&
5105- iseq . body . param . flags . has_lead &&
5106- !iseq . body . param . flags . ambiguous_param0
5107- asm . incr_counter ( :invokeblock_iseq_arg0_splat )
5108- return CantCompile
5109- end
5110-
5111- if calling . argc != iseq . body . param . lead_num
5112- if arg_setup_type == :arg_setup_block
5113- if calling . argc < iseq . body . param . lead_num
5114- ( iseq . body . param . lead_num - calling . argc ) . times do
5115- asm . mov ( ctx . stack_push , Qnil )
5116- end
5117- calling . argc = iseq . body . param . lead_num # fill rest parameters
5118- elsif calling . argc > iseq . body . param . lead_num
5119- ctx . stack_pop ( calling . argc - iseq . body . param . lead_num )
5120- calling . argc = iseq . body . param . lead_num # simply truncate arguments
5121- end
5122- else # not used yet
5123- asm . incr_counter ( :invokeblock_iseq_arity )
5124- return CantCompile
5125- end
5126- end
5127-
5128- return 0
5129- else
5130- return jit_setup_parameters_complex ( jit , ctx , asm , calling . flags , calling . argc , iseq , arg_setup_type :)
5131- end
5132- end
5133-
5134- # setup_parameters_complex (ISEQ only)
5135- # @param jit [RubyVM::RJIT::JITState]
5136- # @param ctx [RubyVM::RJIT::Context]
5137- # @param asm [RubyVM::RJIT::Assembler]
5138- def jit_setup_parameters_complex ( jit , ctx , asm , flags , argc , iseq , arg_setup_type : nil )
5139- min_argc = iseq . body . param . lead_num + iseq . body . param . post_num
5140- max_argc = ( iseq . body . param . flags . has_rest == false ) ? min_argc + iseq . body . param . opt_num : C ::UNLIMITED_ARGUMENTS
5141- kw_flag = flags & ( C ::VM_CALL_KWARG | C ::VM_CALL_KW_SPLAT | C ::VM_CALL_KW_SPLAT_MUT )
5142- opt_pc = 0
5143- keyword_hash = nil
5144- flag_keyword_hash = nil
5145- given_argc = argc
5146-
5147- if kw_flag & C ::VM_CALL_KWARG != 0
5148- asm . incr_counter ( :send_iseq_complex_kwarg )
5149- return CantCompile
5150- end
5151-
5152- if flags & C ::VM_CALL_ARGS_SPLAT != 0 && flags & C ::VM_CALL_KW_SPLAT != 0
5153- asm . incr_counter ( :send_iseq_complex_kw_splat )
5154- return CantCompile
5155- elsif flags & C ::VM_CALL_ARGS_SPLAT != 0
5156- # Lazily handle splat in jit_call_iseq_setup_normal
5157- else
5158- if argc > 0 && kw_flag & C ::VM_CALL_KW_SPLAT != 0
5159- asm . incr_counter ( :send_iseq_complex_kw_splat )
5160- return CantCompile
5161- end
5162- end
5163-
5164- if flag_keyword_hash && C . RB_TYPE_P ( flag_keyword_hash , C ::RUBY_T_HASH )
5165- raise NotImplementedError # unreachable
5166- end
5167-
5168- if kw_flag != 0 && iseq . body . param . flags . accepts_no_kwarg
5169- asm . incr_counter ( :send_iseq_complex_accepts_no_kwarg )
5170- return CantCompile
5171- end
5172-
5173- case arg_setup_type
5174- when :arg_setup_block
5175- asm . incr_counter ( :send_iseq_complex_arg_setup_block )
5176- return CantCompile
5177- end
5178-
5179- if given_argc < min_argc
5180- asm . incr_counter ( :send_iseq_complex_arity )
5181- return CantCompile
5182- end
5183-
5184- if given_argc > max_argc && max_argc != C ::UNLIMITED_ARGUMENTS
5185- asm . incr_counter ( :send_iseq_complex_arity )
5186- return CantCompile
5187- end
5188-
5189- if iseq . body . param . flags . has_lead
5190- asm . incr_counter ( :send_iseq_complex_has_lead )
5191- return CantCompile
5192- end
5193-
5194- if iseq . body . param . flags . has_rest || iseq . body . param . flags . has_post
5195- asm . incr_counter ( iseq . body . param . flags . has_rest ? :send_iseq_complex_has_rest : :send_iseq_complex_has_post )
5196- return CantCompile
5197- end
5198-
5199- if iseq . body . param . flags . has_post
5200- asm . incr_counter ( :send_iseq_complex_has_post )
5201- return CantCompile
5202- end
5203-
5204- if iseq . body . param . flags . has_opt
5205- asm . incr_counter ( :send_iseq_complex_has_opt )
5206- return CantCompile
5207- end
5208-
5209- if iseq . body . param . flags . has_rest
5210- asm . incr_counter ( :send_iseq_complex_has_rest )
5211- return CantCompile
5212- end
5213-
5214- if iseq . body . param . flags . has_kw
5215- asm . incr_counter ( :send_iseq_complex_has_kw )
5216- return CantCompile
5217- elsif iseq . body . param . flags . has_kwrest
5218- asm . incr_counter ( :send_iseq_complex_has_kwrest )
5219- return CantCompile
5220- elsif !keyword_hash . nil? && keyword_hash . size > 0 # && arg_setup_type == :arg_setup_method
5221- raise NotImplementedError # unreachable
5222- end
5223-
5224- if iseq . body . param . flags . has_block
5225- if iseq . body . local_iseq . to_i == iseq . to_i
5226- # Do nothing
5227- else
5228- asm . incr_counter ( :send_iseq_complex_has_block )
5229- return CantCompile
5230- end
5231- end
5232-
5233- return opt_pc
5234- end
5235-
52364968 # CALLER_SETUP_ARG: Return CantCompile if not supported
52374969 # @param jit [RubyVM::RJIT::JITState]
52384970 # @param ctx [RubyVM::RJIT::Context]
@@ -5243,7 +4975,7 @@ def jit_caller_setup_arg(jit, ctx, asm, flags, splat: false)
52434975 return CantCompile
52444976 elsif flags & C ::VM_CALL_ARGS_SPLAT != 0
52454977 if splat
5246- # Lazily handle splat in jit_call_iseq_setup_normal, jit_call_cfunc_with_frame
4978+ # Lazily handle splat in jit_call_cfunc_with_frame
52474979 else
52484980 # splat is not supported in this path
52494981 asm . incr_counter ( :send_args_splat )
0 commit comments