Skip to content

Commit 2e2d235

Browse files
committed
ZJIT: Reject builtin annotation if its iseq has multiple invokebuiltin insns
1 parent f664713 commit 2e2d235

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

zjit/src/cruby_methods.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ fn annotate_builtin_method(props_map: &mut HashMap<*mut c_void, FnProperties>, c
107107

108108
// Scan through the ISEQ to find invokebuiltin instructions
109109
let mut insn_idx: u32 = 0;
110+
let mut func_ptr = std::ptr::null_mut::<c_void>();
111+
110112
while insn_idx < encoded_size {
111113
// Get the PC for this instruction index
112114
let pc = rb_iseq_pc_at_idx(iseq, insn_idx);
@@ -120,13 +122,22 @@ fn annotate_builtin_method(props_map: &mut HashMap<*mut c_void, FnProperties>, c
120122
// The first operand is the builtin function pointer
121123
let bf_value = *pc.add(1);
122124
let bf_ptr = bf_value.as_ptr() as *const rb_builtin_function;
123-
let func_ptr = (*bf_ptr).func_ptr as *mut c_void;
124-
props_map.insert(func_ptr, props);
125+
126+
if func_ptr.is_null() {
127+
func_ptr = (*bf_ptr).func_ptr as *mut c_void;
128+
} else {
129+
panic!("Multiple invokebuiltin instructions found in ISEQ for {}#{}",
130+
std::ffi::CStr::from_ptr(rb_class2name(class)).to_str().unwrap_or("?"),
131+
method_name);
132+
}
125133
}
126134

127135
// Move to the next instruction using the proper length
128136
insn_idx = insn_idx.saturating_add(rb_insn_len(VALUE(opcode as usize)).try_into().unwrap());
129137
}
138+
139+
// Only insert the properties if its iseq has exactly one invokebuiltin instruction
140+
props_map.insert(func_ptr, props);
130141
}
131142
}
132143

0 commit comments

Comments
 (0)