@@ -523,6 +523,13 @@ pub enum Insn {
523523
524524 // Invoke a builtin function
525525 InvokeBuiltin { bf : rb_builtin_function , args : Vec < InsnId > , state : InsnId } ,
526+ /// Call a builtin function with known return type
527+ BuiltinCall {
528+ bf : rb_builtin_function ,
529+ args : Vec < InsnId > ,
530+ state : InsnId ,
531+ return_type : Type ,
532+ } ,
526533
527534 /// Control flow instructions
528535 Return { val : InsnId } ,
@@ -705,6 +712,13 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
705712 }
706713 Ok ( ( ) )
707714 }
715+ Insn :: BuiltinCall { bf, args, .. } => {
716+ write ! ( f, "BuiltinCall {}" , unsafe { CStr :: from_ptr( bf. name) } . to_str( ) . unwrap( ) ) ?;
717+ for arg in args {
718+ write ! ( f, ", {arg}" ) ?;
719+ }
720+ Ok ( ( ) )
721+ }
708722 Insn :: Return { val } => { write ! ( f, "Return {val}" ) }
709723 Insn :: FixnumAdd { left, right, .. } => { write ! ( f, "FixnumAdd {left}, {right}" ) } ,
710724 Insn :: FixnumSub { left, right, .. } => { write ! ( f, "FixnumSub {left}, {right}" ) } ,
@@ -1160,6 +1174,7 @@ impl Function {
11601174 state,
11611175 } ,
11621176 & InvokeBuiltin { bf, ref args, state } => InvokeBuiltin { bf : bf, args : find_vec ! ( args) , state } ,
1177+ & BuiltinCall { bf, ref args, state, return_type } => BuiltinCall { bf : bf, args : find_vec ! ( args) , state, return_type } ,
11631178 & ArrayDup { val, state } => ArrayDup { val : find ! ( val) , state } ,
11641179 & HashDup { val, state } => HashDup { val : find ! ( val) , state } ,
11651180 & CCall { cfun, ref args, name, return_type, elidable } => CCall { cfun, args : find_vec ! ( args) , name, return_type, elidable } ,
@@ -1257,6 +1272,7 @@ impl Function {
12571272 Insn :: SendWithoutBlockDirect { .. } => types:: BasicObject ,
12581273 Insn :: Send { .. } => types:: BasicObject ,
12591274 Insn :: InvokeBuiltin { .. } => types:: BasicObject ,
1275+ Insn :: BuiltinCall { return_type, .. } => * return_type,
12601276 Insn :: Defined { .. } => types:: BasicObject ,
12611277 Insn :: DefinedIvar { .. } => types:: BasicObject ,
12621278 Insn :: GetConstantPath { .. } => types:: BasicObject ,
@@ -1915,6 +1931,10 @@ impl Function {
19151931 worklist. extend ( args) ;
19161932 worklist. push_back ( state)
19171933 }
1934+ & Insn :: BuiltinCall { ref args, state, .. } => {
1935+ worklist. extend ( args) ;
1936+ worklist. push_back ( state)
1937+ }
19181938 & Insn :: CCall { ref args, .. } => worklist. extend ( args) ,
19191939 & Insn :: GetIvar { self_val, state, .. } | & Insn :: DefinedIvar { self_val, state, .. } => {
19201940 worklist. push_back ( self_val) ;
@@ -3115,7 +3135,21 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
31153135 args. reverse ( ) ;
31163136
31173137 let exit_id = fun. push_insn ( block, Insn :: Snapshot { state : exit_state } ) ;
3118- let insn_id = fun. push_insn ( block, Insn :: InvokeBuiltin { bf, args, state : exit_id } ) ;
3138+
3139+ // Check if this builtin is annotated
3140+ let builtin_name = unsafe { CStr :: from_ptr ( bf. name ) . to_str ( ) . unwrap ( ) } ;
3141+ let insn_id = if let Some ( props) = ZJITState :: get_method_annotations ( ) . get_builtin_properties ( builtin_name) {
3142+ // Use BuiltinCall with known return type
3143+ fun. push_insn ( block, Insn :: BuiltinCall {
3144+ bf,
3145+ args,
3146+ state : exit_id,
3147+ return_type : props. return_type ,
3148+ } )
3149+ } else {
3150+ // Fall back to InvokeBuiltin for unannotated builtins
3151+ fun. push_insn ( block, Insn :: InvokeBuiltin { bf, args, state : exit_id } )
3152+ } ;
31193153 state. stack_push ( insn_id) ;
31203154 }
31213155 YARVINSN_opt_invokebuiltin_delegate |
@@ -3130,7 +3164,21 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
31303164 }
31313165
31323166 let exit_id = fun. push_insn ( block, Insn :: Snapshot { state : exit_state } ) ;
3133- let insn_id = fun. push_insn ( block, Insn :: InvokeBuiltin { bf, args, state : exit_id } ) ;
3167+
3168+ // Check if this builtin is annotated
3169+ let builtin_name = unsafe { CStr :: from_ptr ( bf. name ) . to_str ( ) . unwrap ( ) } ;
3170+ let insn_id = if let Some ( props) = ZJITState :: get_method_annotations ( ) . get_builtin_properties ( builtin_name) {
3171+ // Use BuiltinCall with known return type
3172+ fun. push_insn ( block, Insn :: BuiltinCall {
3173+ bf,
3174+ args,
3175+ state : exit_id,
3176+ return_type : props. return_type ,
3177+ } )
3178+ } else {
3179+ // Fall back to InvokeBuiltin for unannotated builtins
3180+ fun. push_insn ( block, Insn :: InvokeBuiltin { bf, args, state : exit_id } )
3181+ } ;
31343182 state. stack_push ( insn_id) ;
31353183 }
31363184 YARVINSN_objtostring => {
@@ -4970,12 +5018,28 @@ mod tests {
49705018
49715019 #[ test]
49725020 fn test_invokebuiltin_delegate_with_args ( ) {
5021+ // Using an unannotated builtin to test InvokeBuiltin generation
5022+ let iseq = crate :: cruby:: with_rubyvm ( || get_method_iseq ( "GC" , "start" ) ) ;
5023+ assert ! ( iseq_contains_opcode( iseq, YARVINSN_invokebuiltin ) , "iseq GC.start does not contain invokebuiltin" ) ;
5024+ let function = iseq_to_hir ( iseq) . unwrap ( ) ;
5025+ assert_function_hir ( function, expect ! [ [ r#"
5026+ fn start@<internal:gc>:36:
5027+ bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject, v3:BasicObject, v4:BasicObject):
5028+ v6:FalseClass = Const Value(false)
5029+ v8:BasicObject = InvokeBuiltin gc_start_internal, v0, v1, v2, v3, v6
5030+ Return v8
5031+ "# ] ] ) ;
5032+ }
5033+
5034+ #[ test]
5035+ fn test_invokebuiltin_delegate_annotated ( ) {
5036+ // Test that Float now generates BuiltinCall with correct type
49735037 assert_method_hir_with_opcode ( "Float" , YARVINSN_opt_invokebuiltin_delegate_leave , expect ! [ [ r#"
49745038 fn Float@<internal:kernel>:197:
49755039 bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject, v3:BasicObject):
4976- v6:BasicObject = InvokeBuiltin rb_f_float, v0, v1, v2
5040+ v6:Flonum = BuiltinCall rb_f_float, v0, v1, v2
49775041 Jump bb1(v0, v1, v2, v3, v6)
4978- bb1(v8:BasicObject, v9:BasicObject, v10:BasicObject, v11:BasicObject, v12:BasicObject ):
5042+ bb1(v8:BasicObject, v9:BasicObject, v10:BasicObject, v11:BasicObject, v12:Flonum ):
49795043 Return v12
49805044 "# ] ] ) ;
49815045 }
0 commit comments