Skip to content

Commit 30a20bc

Browse files
st0012k0kubun
authored andcommitted
ZJIT: Reject builtin annotation if its iseq has multiple invokebuiltin insns
1 parent 44dee18 commit 30a20bc

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

zjit/src/cruby_methods.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)