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