Skip to content

Commit c822ec5

Browse files
author
hyd-dev
committed
Implement cache for not found symbols
1 parent ce70400 commit c822ec5

File tree

3 files changed

+11
-8
lines changed

3 files changed

+11
-8
lines changed

src/machine.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ pub struct Evaluator<'mir, 'tcx> {
297297
string_cache: FxHashMap<String, measureme::StringId>,
298298

299299
/// Cache of `Instance` exported under the given `Symbol` name.
300-
pub(crate) exported_symbols_cache: FxHashMap<Symbol, Instance<'tcx>>,
300+
/// `None` means no `Instance` exported under the given name is found.
301+
pub(crate) exported_symbols_cache: FxHashMap<Symbol, Option<Instance<'tcx>>>,
301302

302303
/// Whether to raise a panic in the context of the evaluated process when unsupported
303304
/// functionality is encountered. If `false`, an error is propagated in the Miri application context

src/shims/foreign_items.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
135135

136136
// If the result was cached, just return it.
137137
if let Some(instance) = this.machine.exported_symbols_cache.get(&link_name) {
138-
return Ok(Some(this.load_mir(instance.def, None)?));
138+
return instance.map(|instance| this.load_mir(instance.def, None)).transpose();
139139
}
140140

141141
// Find it if it was not cached.
@@ -187,13 +187,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
187187
}
188188
}
189189

190+
let instance = instance_and_crate.map(|ic| ic.0);
190191
// Cache it and load its MIR, if found.
191-
instance_and_crate
192-
.map(|(instance, _)| {
193-
this.machine.exported_symbols_cache.insert(link_name, instance);
194-
this.load_mir(instance.def, None)
195-
})
196-
.transpose()
192+
this.machine.exported_symbols_cache.insert(link_name, instance);
193+
instance.map(|instance| this.load_mir(instance.def, None)).transpose()
197194
}
198195

199196
/// Emulates calling a foreign item, failing if the item is not supported.

tests/run-pass/function_calls/exported_symbol.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@ fn main() {
2020
for _ in 0..3 {
2121
extern "C" {
2222
fn foo() -> i32;
23+
fn free(_: *mut std::ffi::c_void);
2324
}
2425

2526
assert_eq!(unsafe { foo() }, -1);
2627

28+
// `free()` is a built-in shim, so calling it will add ("free", None) to the cache.
29+
// Test that the cache is not broken with ("free", None).
30+
unsafe { free(std::ptr::null_mut()) }
31+
2732
extern "Rust" {
2833
fn bar() -> i32;
2934
fn baz() -> i32;

0 commit comments

Comments
 (0)