@@ -1623,7 +1623,7 @@ fn gen_send_iseq_direct(
16231623 }
16241624
16251625 // Make a method call. The target address will be rewritten once compiled.
1626- let iseq_call = IseqCall :: new ( iseq, num_optionals_passed) ;
1626+ let iseq_call = IseqCall :: new ( iseq, num_optionals_passed, args . len ( ) . try_into ( ) . expect ( "TODO: no panic here from downcast from usize" ) ) ;
16271627 let dummy_ptr = cb. get_write_ptr ( ) . raw_ptr ( cb) ;
16281628 jit. iseq_calls . push ( iseq_call. clone ( ) ) ;
16291629 let ret = asm. ccall_with_iseq_call ( dummy_ptr, c_args, & iseq_call) ;
@@ -2865,22 +2865,37 @@ c_callable! {
28652865 // function_stub_hit_body() may allocate and call gc_validate_pc(), so we always set PC.
28662866 let iseq_call = unsafe { Rc :: from_raw( iseq_call_ptr as * const IseqCall ) } ;
28672867 let iseq = iseq_call. iseq. get( ) ;
2868+ let argc = iseq_call. argc;
2869+ let num_opts_filled = iseq_call. jit_entry_idx;
28682870 let entry_insn_idxs = crate :: hir:: jit_entry_insns( iseq) ;
28692871 let pc = unsafe { rb_iseq_pc_at_idx( iseq, entry_insn_idxs[ iseq_call. jit_entry_idx. to_usize( ) ] ) } ;
28702872 unsafe { rb_set_cfp_pc( cfp, pc) } ;
28712873
28722874 // Successful JIT-to-JIT calls fill nils to non-parameter locals in generated code.
28732875 // If we side-exit from function_stub_hit (before JIT code runs), we need to set them here.
2874- fn prepare_for_exit( iseq: IseqPtr , cfp: CfpPtr , sp: * mut VALUE , compile_error: & CompileError ) {
2876+ fn prepare_for_exit( iseq: IseqPtr , cfp: CfpPtr , sp: * mut VALUE , argc : u32 , num_opts_filled : u32 , compile_error: & CompileError ) {
28752877 unsafe {
28762878 // Set SP which gen_push_frame() doesn't set
28772879 rb_set_cfp_sp( cfp, sp) ;
28782880
2879- // Fill nils to uninitialized (non-argument ) locals
2881+ // Fill nils to uninitialized (non-parameter ) locals
28802882 let local_size = get_iseq_body_local_table_size( iseq) . to_usize( ) ;
2881- let num_params = iseq. params( ) . size. to_usize( ) ;
2883+ let params = iseq. params( ) ;
2884+ let num_params = params. size. to_usize( ) ;
28822885 let base = sp. offset( -local_size_and_idx_to_bp_offset( local_size, num_params) as isize ) ;
2886+ // TODO one slice for everything
28832887 slice:: from_raw_parts_mut( base, local_size - num_params) . fill( Qnil ) ;
2888+
2889+ let opt_num: usize = params. opt_num. try_into( ) . expect( "ISEQ opt_num should be non-negative" ) ;
2890+ let lead_num: usize = params. lead_num. try_into( ) . expect( "should be non-negative" ) ;
2891+ let after_opts = lead_num + opt_num;
2892+
2893+ // TODO rename
2894+ let base = sp. offset( -local_size_and_idx_to_bp_offset( local_size, 0 ) as isize ) ;
2895+ let params = slice:: from_raw_parts_mut( base, num_params) ;
2896+ params. copy_within( num_opts_filled. to_usize( ) ..argc. to_usize( ) , after_opts) ;
2897+
2898+ ( & mut params[ num_opts_filled. to_usize( ) ..after_opts] ) . fill( Qnil ) ;
28842899 }
28852900
28862901 // Increment a compile error counter for --zjit-stats
@@ -2904,7 +2919,7 @@ c_callable! {
29042919 // We'll use this Rc again, so increment the ref count decremented by from_raw.
29052920 unsafe { Rc :: increment_strong_count( iseq_call_ptr as * const IseqCall ) ; }
29062921
2907- prepare_for_exit( iseq, cfp, sp, compile_error) ;
2922+ prepare_for_exit( iseq, cfp, sp, argc , num_opts_filled , compile_error) ;
29082923 return ZJITState :: get_exit_trampoline_with_counter( ) . raw_ptr( cb) ;
29092924 }
29102925
@@ -2919,7 +2934,7 @@ c_callable! {
29192934 // We'll use this Rc again, so increment the ref count decremented by from_raw.
29202935 unsafe { Rc :: increment_strong_count( iseq_call_ptr as * const IseqCall ) ; }
29212936
2922- prepare_for_exit( iseq, cfp, sp, & compile_error) ;
2937+ prepare_for_exit( iseq, cfp, sp, argc , num_opts_filled , & compile_error) ;
29232938 ZJITState :: get_exit_trampoline_with_counter( )
29242939 } ) ;
29252940 cb. mark_all_executable( ) ;
@@ -3246,6 +3261,9 @@ pub struct IseqCall {
32463261 /// Index that corresponds to [crate::hir::jit_entry_insns]
32473262 jit_entry_idx : u32 ,
32483263
3264+ /// Argument count passing to the HIR function
3265+ argc : u32 ,
3266+
32493267 /// Position where the call instruction starts
32503268 start_addr : Cell < Option < CodePtr > > ,
32513269
@@ -3257,12 +3275,13 @@ pub type IseqCallRef = Rc<IseqCall>;
32573275
32583276impl IseqCall {
32593277 /// Allocate a new IseqCall
3260- fn new ( iseq : IseqPtr , jit_entry_idx : u32 ) -> IseqCallRef {
3278+ fn new ( iseq : IseqPtr , jit_entry_idx : u32 , argc : u32 ) -> IseqCallRef {
32613279 let iseq_call = IseqCall {
32623280 iseq : Cell :: new ( iseq) ,
32633281 start_addr : Cell :: new ( None ) ,
32643282 end_addr : Cell :: new ( None ) ,
32653283 jit_entry_idx,
3284+ argc,
32663285 } ;
32673286 Rc :: new ( iseq_call)
32683287 }
0 commit comments