@@ -141,7 +141,7 @@ fn gen_entry(cb: &mut CodeBlock, iseq: IseqPtr, function: &Function, function_pt
141141 // Set up registers for CFP, EC, SP, and basic block arguments
142142 let mut asm = Assembler :: new ( ) ;
143143 gen_entry_prologue ( & mut asm, iseq) ;
144- gen_method_params ( & mut asm, iseq, function. block ( BlockId ( 0 ) ) ) ;
144+ gen_method_params ( & mut asm, iseq, function. block ( BlockId ( 0 ) ) ) ? ;
145145
146146 // Jump to the first block using a call instruction
147147 asm. ccall ( function_ptr. raw_ptr ( cb) as * const u8 , vec ! [ ] ) ;
@@ -207,7 +207,7 @@ fn gen_function(cb: &mut CodeBlock, iseq: IseqPtr, function: &Function) -> Optio
207207 for & insn_id in block. params ( ) {
208208 match function. find ( insn_id) {
209209 Insn :: Param { idx } => {
210- jit. opnds [ insn_id. 0 ] = Some ( gen_param ( & mut asm, idx) ) ;
210+ jit. opnds [ insn_id. 0 ] = Some ( gen_param ( & mut asm, idx) ? ) ;
211211 } ,
212212 insn => unreachable ! ( "Non-param insn found in block.params: {insn:?}" ) ,
213213 }
@@ -319,14 +319,17 @@ fn gen_entry_prologue(asm: &mut Assembler, iseq: IseqPtr) {
319319}
320320
321321/// Assign method arguments to basic block arguments at JIT entry
322- fn gen_method_params ( asm : & mut Assembler , iseq : IseqPtr , entry_block : & Block ) {
322+ fn gen_method_params ( asm : & mut Assembler , iseq : IseqPtr , entry_block : & Block ) -> Option < ( ) > {
323323 let num_params = entry_block. params ( ) . len ( ) ;
324324 if num_params > 0 {
325325 asm_comment ! ( asm, "set method params: {num_params}" ) ;
326326
327327 // Allocate registers for basic block arguments
328+ if num_params >= ALLOC_REGS . len ( ) {
329+ return None ;
330+ }
328331 let params: Vec < Opnd > = ( 0 ..num_params) . map ( |idx|
329- gen_param ( asm, idx)
332+ gen_param ( asm, idx) . unwrap ( )
330333 ) . collect ( ) ;
331334
332335 // Assign local variables to the basic block arguments
@@ -335,6 +338,7 @@ fn gen_method_params(asm: &mut Assembler, iseq: IseqPtr, entry_block: &Block) {
335338 asm. load_into ( param, local) ;
336339 }
337340 }
341+ Some ( ( ) )
338342}
339343
340344/// Set branch params to basic block arguments
@@ -343,7 +347,7 @@ fn gen_branch_params(jit: &mut JITState, asm: &mut Assembler, branch: &BranchEdg
343347 asm_comment ! ( asm, "set branch params: {}" , branch. args. len( ) ) ;
344348 let mut moves: Vec < ( Reg , Opnd ) > = vec ! [ ] ;
345349 for ( idx, & arg) in branch. args . iter ( ) . enumerate ( ) {
346- moves. push ( ( param_reg ( idx) , jit. get_opnd ( arg) ?) ) ;
350+ moves. push ( ( param_reg ( idx) ? , jit. get_opnd ( arg) ?) ) ;
347351 }
348352 asm. parallel_mov ( moves) ;
349353 }
@@ -382,14 +386,14 @@ fn gen_const(val: VALUE) -> lir::Opnd {
382386}
383387
384388/// Compile a basic block argument
385- fn gen_param ( asm : & mut Assembler , idx : usize ) -> lir:: Opnd {
386- asm. live_reg_opnd ( Opnd :: Reg ( param_reg ( idx) ) )
389+ fn gen_param ( asm : & mut Assembler , idx : usize ) -> Option < lir:: Opnd > {
390+ Some ( asm. live_reg_opnd ( Opnd :: Reg ( param_reg ( idx) ? ) ) )
387391}
388392
389393/// Compile a jump to a basic block
390394fn gen_jump ( jit : & mut JITState , asm : & mut Assembler , branch : & BranchEdge ) -> Option < ( ) > {
391395 // Set basic block arguments
392- gen_branch_params ( jit, asm, branch) ;
396+ gen_branch_params ( jit, asm, branch) ? ;
393397
394398 // Jump to the basic block
395399 let target = jit. get_label ( asm, branch. target ) ;
@@ -407,7 +411,7 @@ fn gen_if_true(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, branch:
407411 // If val is not zero, set basic block arguments and jump to the branch target.
408412 // TODO: Consider generating the loads out-of-line
409413 let if_true = jit. get_label ( asm, branch. target ) ;
410- gen_branch_params ( jit, asm, branch) ;
414+ gen_branch_params ( jit, asm, branch) ? ;
411415 asm. jmp ( if_true) ;
412416
413417 asm. write_label ( if_false) ;
@@ -425,7 +429,7 @@ fn gen_if_false(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, branch:
425429 // If val is zero, set basic block arguments and jump to the branch target.
426430 // TODO: Consider generating the loads out-of-line
427431 let if_false = jit. get_label ( asm, branch. target ) ;
428- gen_branch_params ( jit, asm, branch) ;
432+ gen_branch_params ( jit, asm, branch) ? ;
429433 asm. jmp ( if_false) ;
430434
431435 asm. write_label ( if_true) ;
@@ -699,10 +703,10 @@ fn gen_push_frame(asm: &mut Assembler, recv: Opnd) {
699703}
700704
701705/// Return a register we use for the basic block argument at a given index
702- fn param_reg ( idx : usize ) -> Reg {
706+ fn param_reg ( idx : usize ) -> Option < Reg > {
703707 // To simplify the implementation, allocate a fixed register for each basic block argument for now.
704708 // TODO: Allow allocating arbitrary registers for basic block arguments
705- ALLOC_REGS [ idx]
709+ ALLOC_REGS . get ( idx) . copied ( )
706710}
707711
708712/// Inverse of ep_offset_to_local_idx(). See ep_offset_to_local_idx() for details.
0 commit comments