Skip to content

Commit 04b9b4a

Browse files
committed
ZJIT: Reject builtin annotation if its iseq has multiple invokebuiltin insns
1 parent d4a000f commit 04b9b4a

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
@@ -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

Comments
 (0)