@@ -1630,7 +1630,7 @@ fn gen_send_iseq_direct(
16301630 }
16311631
16321632 // Make a method call. The target address will be rewritten once compiled.
1633- let iseq_call = IseqCall :: new ( iseq, num_optionals_passed) ;
1633+ let iseq_call = IseqCall :: new ( iseq, num_optionals_passed, args . len ( ) . try_into ( ) . expect ( "TODO: no panic here from downcast from usize" ) ) ;
16341634 let dummy_ptr = cb. get_write_ptr ( ) . raw_ptr ( cb) ;
16351635 jit. iseq_calls . push ( iseq_call. clone ( ) ) ;
16361636 let ret = asm. ccall_with_iseq_call ( dummy_ptr, c_args, & iseq_call) ;
@@ -2872,22 +2872,40 @@ c_callable! {
28722872 // function_stub_hit_body() may allocate and call gc_validate_pc(), so we always set PC.
28732873 let iseq_call = unsafe { Rc :: from_raw( iseq_call_ptr as * const IseqCall ) } ;
28742874 let iseq = iseq_call. iseq. get( ) ;
2875+ let argc = iseq_call. argc;
2876+ let num_opts_filled = iseq_call. jit_entry_idx;
28752877 let entry_insn_idxs = crate :: hir:: jit_entry_insns( iseq) ;
28762878 let pc = unsafe { rb_iseq_pc_at_idx( iseq, entry_insn_idxs[ iseq_call. jit_entry_idx. to_usize( ) ] ) } ;
28772879 unsafe { rb_set_cfp_pc( cfp, pc) } ;
28782880
28792881 // Successful JIT-to-JIT calls fill nils to non-parameter locals in generated code.
28802882 // If we side-exit from function_stub_hit (before JIT code runs), we need to set them here.
2881- fn prepare_for_exit( iseq: IseqPtr , cfp: CfpPtr , sp: * mut VALUE , compile_error: & CompileError ) {
2883+ fn prepare_for_exit( iseq: IseqPtr , cfp: CfpPtr , sp: * mut VALUE , argc : u32 , num_opts_filled : u32 , compile_error: & CompileError ) {
28822884 unsafe {
28832885 // Set SP which gen_push_frame() doesn't set
28842886 rb_set_cfp_sp( cfp, sp) ;
28852887
2886- // Fill nils to uninitialized (non-argument ) locals
2888+ // Fill nils to uninitialized (non-parameter ) locals
28872889 let local_size = get_iseq_body_local_table_size( iseq) . to_usize( ) ;
2888- let num_params = iseq. params( ) . size. to_usize( ) ;
2890+ let params = iseq. params( ) ;
2891+ let num_params = params. size. to_usize( ) ;
28892892 let base = sp. offset( -local_size_and_idx_to_bp_offset( local_size, num_params) as isize ) ;
2893+ // TODO one slice for everything
28902894 slice:: from_raw_parts_mut( base, local_size - num_params) . fill( Qnil ) ;
2895+
2896+ let opt_num: usize = params. opt_num. try_into( ) . expect( "ISEQ opt_num should be non-negative" ) ;
2897+ let num_opts_unfilled = opt_num - num_opts_filled. to_usize( ) ;
2898+ if num_opts_unfilled > 0 {
2899+ let lead_num: usize = params. lead_num. try_into( ) . expect( "should be non-negative" ) ;
2900+ let after_opts = lead_num + opt_num;
2901+
2902+ // TODO rename
2903+ let base = sp. offset( -local_size_and_idx_to_bp_offset( local_size, 0 ) as isize ) ;
2904+ let params = slice:: from_raw_parts_mut( base, num_params) ;
2905+ params. copy_within( num_opts_filled. to_usize( ) ..argc. to_usize( ) , after_opts) ;
2906+
2907+ ( & mut params[ num_opts_filled. to_usize( ) ..after_opts] ) . fill( Qnil ) ;
2908+ }
28912909 }
28922910
28932911 // Increment a compile error counter for --zjit-stats
@@ -2911,7 +2929,7 @@ c_callable! {
29112929 // We'll use this Rc again, so increment the ref count decremented by from_raw.
29122930 unsafe { Rc :: increment_strong_count( iseq_call_ptr as * const IseqCall ) ; }
29132931
2914- prepare_for_exit( iseq, cfp, sp, compile_error) ;
2932+ prepare_for_exit( iseq, cfp, sp, argc , num_opts_filled , compile_error) ;
29152933 return ZJITState :: get_exit_trampoline_with_counter( ) . raw_ptr( cb) ;
29162934 }
29172935
@@ -2926,7 +2944,7 @@ c_callable! {
29262944 // We'll use this Rc again, so increment the ref count decremented by from_raw.
29272945 unsafe { Rc :: increment_strong_count( iseq_call_ptr as * const IseqCall ) ; }
29282946
2929- prepare_for_exit( iseq, cfp, sp, & compile_error) ;
2947+ prepare_for_exit( iseq, cfp, sp, argc , num_opts_filled , & compile_error) ;
29302948 ZJITState :: get_exit_trampoline_with_counter( )
29312949 } ) ;
29322950 cb. mark_all_executable( ) ;
@@ -3253,6 +3271,9 @@ pub struct IseqCall {
32533271 /// Index that corresponds to [crate::hir::jit_entry_insns]
32543272 jit_entry_idx : u32 ,
32553273
3274+ /// Argument count passing to the HIR function
3275+ argc : u32 ,
3276+
32563277 /// Position where the call instruction starts
32573278 start_addr : Cell < Option < CodePtr > > ,
32583279
@@ -3264,12 +3285,13 @@ pub type IseqCallRef = Rc<IseqCall>;
32643285
32653286impl IseqCall {
32663287 /// Allocate a new IseqCall
3267- fn new ( iseq : IseqPtr , jit_entry_idx : u32 ) -> IseqCallRef {
3288+ fn new ( iseq : IseqPtr , jit_entry_idx : u32 , argc : u32 ) -> IseqCallRef {
32683289 let iseq_call = IseqCall {
32693290 iseq : Cell :: new ( iseq) ,
32703291 start_addr : Cell :: new ( None ) ,
32713292 end_addr : Cell :: new ( None ) ,
32723293 jit_entry_idx,
3294+ argc,
32733295 } ;
32743296 Rc :: new ( iseq_call)
32753297 }
0 commit comments