Skip to content

Commit eba954b

Browse files
committed
Extend m_call to be able to filter by name
1 parent 0167726 commit eba954b

File tree

3 files changed

+35
-9
lines changed

3 files changed

+35
-9
lines changed

docs/matchers/call.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
| Function | Parameters | Return | Description |
44
| :---------: | :---------: | :---------: | :-------------------------------------------------------------------------: |
5-
| m_call | | InstMatcher | Build Inst Matcher that match call instruction |
5+
| m_call | (n : Text?) | InstMatcher | Build Inst Matcher that match call instruction with optional name |
66
| m_intrinsic | (n : Text?) | InstMatcher | Build Inst Matcher that match intrinsic call instruction with optional name |

src/functions/matchers/call.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,32 @@ pub fn register_call_inst_matchers_functions(map: &mut HashMap<&'static str, Sta
1919

2020
#[inline(always)]
2121
pub fn register_call_inst_matchers_function_signatures(map: &mut HashMap<&'static str, Signature>) {
22-
map.insert("m_call", Signature::with_return(Box::new(InstMatcherType)));
22+
map.insert(
23+
"m_call",
24+
Signature::with_return(Box::new(InstMatcherType))
25+
.add_parameter(Box::new(OptionType::new(Some(Box::new(TextType))))),
26+
);
27+
2328
map.insert(
2429
"m_intrinsic",
2530
Signature::with_return(Box::new(InstMatcherType))
2631
.add_parameter(Box::new(OptionType::new(Some(Box::new(TextType))))),
2732
);
2833
}
2934

30-
fn match_call_inst(_values: &[Box<dyn Value>]) -> Box<dyn Value> {
31-
let matcher = Box::new(CallInstMatcher::create_call());
35+
fn match_call_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> {
36+
let function_name = if values.is_empty() {
37+
None
38+
} else {
39+
values[0].as_text()
40+
};
41+
42+
let matcher = Box::new(CallInstMatcher::create_call(function_name));
3243
Box::new(InstMatcherValue { matcher })
3344
}
3445

3546
fn match_intrinsic_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> {
36-
let intrinsic_name: Option<String> = if values.is_empty() {
47+
let intrinsic_name = if values.is_empty() {
3748
None
3849
} else {
3950
values[0].as_text()

src/matchers/call.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,33 @@ use inkwell::llvm_sys::LLVMOpcode;
1010
use super::Matcher;
1111

1212
#[derive(Clone)]
13-
pub struct CallInstMatcher;
13+
pub struct CallInstMatcher {
14+
pub name: Option<String>,
15+
}
1416

1517
impl CallInstMatcher {
16-
pub fn create_call() -> Self {
17-
CallInstMatcher
18+
pub fn create_call(name: Option<String>) -> Self {
19+
CallInstMatcher { name }
1820
}
1921
}
2022

2123
impl Matcher<LLVMValueRef> for CallInstMatcher {
2224
#[allow(clippy::not_unsafe_ptr_arg_deref)]
2325
fn is_match(&self, instruction: &LLVMValueRef) -> bool {
24-
unsafe { LLVMGetInstructionOpcode(*instruction) == LLVMOpcode::LLVMCall }
26+
unsafe {
27+
if LLVMGetInstructionOpcode(*instruction) == LLVMOpcode::LLVMCall {
28+
if let Some(expected_name) = &self.name {
29+
let called_value = LLVMGetCalledValue(*instruction);
30+
let mut len: usize = 0;
31+
let name_ptr = LLVMGetValueName2(called_value, &mut len);
32+
let name_slice = std::slice::from_raw_parts(name_ptr as *const u8, len);
33+
let name = std::str::from_utf8_unchecked(name_slice).to_string();
34+
return name.eq(expected_name);
35+
}
36+
return true;
37+
}
38+
}
39+
false
2540
}
2641
}
2742

0 commit comments

Comments
 (0)