@@ -99,6 +99,8 @@ fn annotate_builtin_method(props_map: &mut HashMap<*mut c_void, FnProperties>, c
9999
100100 // Scan through the ISEQ to find invokebuiltin instructions
101101 let mut insn_idx: u32 = 0 ;
102+ let mut func_ptr = std:: ptr:: null_mut :: < c_void > ( ) ;
103+
102104 while insn_idx < encoded_size {
103105 // Get the PC for this instruction index
104106 let pc = rb_iseq_pc_at_idx ( iseq, insn_idx) ;
@@ -112,13 +114,22 @@ fn annotate_builtin_method(props_map: &mut HashMap<*mut c_void, FnProperties>, c
112114 // The first operand is the builtin function pointer
113115 let bf_value = * pc. add ( 1 ) ;
114116 let bf_ptr = bf_value. as_ptr ( ) as * const rb_builtin_function ;
115- let func_ptr = ( * bf_ptr) . func_ptr as * mut c_void ;
116- props_map. insert ( func_ptr, props) ;
117+
118+ if func_ptr. is_null ( ) {
119+ func_ptr = ( * bf_ptr) . func_ptr as * mut c_void ;
120+ } else {
121+ panic ! ( "Multiple invokebuiltin instructions found in ISEQ for {}#{}" ,
122+ std:: ffi:: CStr :: from_ptr( rb_class2name( class) ) . to_str( ) . unwrap_or( "?" ) ,
123+ method_name) ;
124+ }
117125 }
118126
119127 // Move to the next instruction using the proper length
120128 insn_idx = insn_idx. saturating_add ( rb_insn_len ( VALUE ( opcode as usize ) ) . try_into ( ) . unwrap ( ) ) ;
121129 }
130+
131+ // Only insert the properties if its iseq has exactly one invokebuiltin instruction
132+ props_map. insert ( func_ptr, props) ;
122133 }
123134}
124135
0 commit comments