@@ -357,7 +357,10 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
357357 Insn :: SendWithoutBlockDirect { cd, state, self_val, args, .. } if args. len ( ) + 1 > C_ARG_OPNDS . len ( ) => // +1 for self
358358 gen_send_without_block ( jit, asm, * cd, & function. frame_state ( * state) , opnd ! ( self_val) , opnds ! ( args) ) ,
359359 Insn :: SendWithoutBlockDirect { cme, iseq, self_val, args, state, .. } => gen_send_without_block_direct ( cb, jit, asm, * cme, * iseq, opnd ! ( self_val) , opnds ! ( args) , & function. frame_state ( * state) ) ,
360- Insn :: InvokeBuiltin { bf, args, state, .. } => gen_invokebuiltin ( jit, asm, & function. frame_state ( * state) , bf, opnds ! ( args) ) ?,
360+ // Ensure we have enough room fit ec, self, and arguments
361+ // TODO remove this check when we have stack args (we can use Time.new to test it)
362+ Insn :: InvokeBuiltin { bf, .. } if bf. argc + 2 > ( C_ARG_OPNDS . len ( ) as i32 ) => return None ,
363+ Insn :: InvokeBuiltin { bf, args, state, .. } => gen_invokebuiltin ( jit, asm, & function. frame_state ( * state) , bf, opnds ! ( args) ) ,
361364 Insn :: Return { val } => no_output ! ( gen_return( asm, opnd!( val) ) ) ,
362365 Insn :: FixnumAdd { left, right, state } => gen_fixnum_add ( jit, asm, opnd ! ( left) , opnd ! ( right) , & function. frame_state ( * state) ) ,
363366 Insn :: FixnumSub { left, right, state } => gen_fixnum_sub ( jit, asm, opnd ! ( left) , opnd ! ( right) , & function. frame_state ( * state) ) ,
@@ -372,7 +375,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
372375 Insn :: FixnumOr { left, right } => gen_fixnum_or ( asm, opnd ! ( left) , opnd ! ( right) ) ,
373376 Insn :: IsNil { val } => gen_isnil ( asm, opnd ! ( val) ) ,
374377 Insn :: Test { val } => gen_test ( asm, opnd ! ( val) ) ,
375- Insn :: GuardType { val, guard_type, state } => gen_guard_type ( jit, asm, opnd ! ( val) , * guard_type, & function. frame_state ( * state) ) ? ,
378+ Insn :: GuardType { val, guard_type, state } => gen_guard_type ( jit, asm, opnd ! ( val) , * guard_type, & function. frame_state ( * state) ) ,
376379 Insn :: GuardBitEquals { val, expected, state } => gen_guard_bit_equals ( jit, asm, opnd ! ( val) , * expected, & function. frame_state ( * state) ) ,
377380 Insn :: PatchPoint { invariant, state } => no_output ! ( gen_patch_point( jit, asm, invariant, & function. frame_state( * state) ) ) ,
378381 Insn :: CCall { cfun, args, name : _, return_type : _, elidable : _ } => gen_ccall ( asm, * cfun, opnds ! ( args) ) ,
@@ -543,22 +546,18 @@ fn gen_get_constant_path(jit: &JITState, asm: &mut Assembler, ic: *const iseq_in
543546 asm_ccall ! ( asm, rb_vm_opt_getconstant_path, EC , CFP , Opnd :: const_ptr( ic) )
544547}
545548
546- fn gen_invokebuiltin ( jit : & JITState , asm : & mut Assembler , state : & FrameState , bf : & rb_builtin_function , args : Vec < Opnd > ) -> Option < lir:: Opnd > {
547- // Ensure we have enough room fit ec, self, and arguments
548- // TODO remove this check when we have stack args (we can use Time.new to test it)
549- if bf. argc + 2 > ( C_ARG_OPNDS . len ( ) as i32 ) {
550- return None ;
551- }
552-
549+ fn gen_invokebuiltin ( jit : & JITState , asm : & mut Assembler , state : & FrameState , bf : & rb_builtin_function , args : Vec < Opnd > ) -> lir:: Opnd {
550+ assert ! ( bf. argc + 2 <= C_ARG_OPNDS . len( ) as i32 ,
551+ "gen_invokebuiltin should not be called for builtin function {} with too many arguments: {}" ,
552+ unsafe { std:: ffi:: CStr :: from_ptr( bf. name) . to_str( ) . unwrap( ) } ,
553+ bf. argc) ;
553554 // Anything can happen inside builtin functions
554555 gen_prepare_non_leaf_call ( jit, asm, state) ;
555556
556557 let mut cargs = vec ! [ EC ] ;
557558 cargs. extend ( args) ;
558559
559- let val = asm. ccall ( bf. func_ptr as * const u8 , cargs) ;
560-
561- Some ( val)
560+ asm. ccall ( bf. func_ptr as * const u8 , cargs)
562561}
563562
564563/// Record a patch point that should be invalidated on a given invariant
@@ -1173,7 +1172,7 @@ fn gen_test(asm: &mut Assembler, val: lir::Opnd) -> lir::Opnd {
11731172}
11741173
11751174/// Compile a type check with a side exit
1176- fn gen_guard_type ( jit : & mut JITState , asm : & mut Assembler , val : lir:: Opnd , guard_type : Type , state : & FrameState ) -> Option < lir:: Opnd > {
1175+ fn gen_guard_type ( jit : & mut JITState , asm : & mut Assembler , val : lir:: Opnd , guard_type : Type , state : & FrameState ) -> lir:: Opnd {
11771176 if guard_type. is_subtype ( types:: Fixnum ) {
11781177 asm. test ( val, Opnd :: UImm ( RUBY_FIXNUM_FLAG as u64 ) ) ;
11791178 asm. jz ( side_exit ( jit, state, GuardType ( guard_type) ) ) ;
@@ -1186,7 +1185,7 @@ fn gen_guard_type(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, guard
11861185 // Static symbols have (val & 0xff) == RUBY_SYMBOL_FLAG
11871186 // Use 8-bit comparison like YJIT does
11881187 debug_assert ! ( val. try_num_bits( 8 ) . is_some( ) , "GuardType should not be used for a known constant, but val was: {val:?}" ) ;
1189- asm. cmp ( val. try_num_bits ( 8 ) ? , Opnd :: UImm ( RUBY_SYMBOL_FLAG as u64 ) ) ;
1188+ asm. cmp ( val. with_num_bits ( 8 ) , Opnd :: UImm ( RUBY_SYMBOL_FLAG as u64 ) ) ;
11901189 asm. jne ( side_exit ( jit, state, GuardType ( guard_type) ) ) ;
11911190 } else if guard_type. is_subtype ( types:: NilClass ) {
11921191 asm. cmp ( val, Qnil . into ( ) ) ;
@@ -1227,7 +1226,7 @@ fn gen_guard_type(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, guard
12271226 } else {
12281227 unimplemented ! ( "unsupported type: {guard_type}" ) ;
12291228 }
1230- Some ( val)
1229+ val
12311230}
12321231
12331232/// Compile an identity check with a side exit
0 commit comments