Skip to content

Commit a312297

Browse files
committed
adjust for FnAbi changes
1 parent 2170d7a commit a312297

File tree

5 files changed

+89
-75
lines changed

5 files changed

+89
-75
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
41c3017c82bbc16842cc3bc1afa904e6910e293c
1+
59337cddd41880f8075b07860a99be4dc402ddb1

src/helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
687687
link_name: Symbol,
688688
) -> InterpResult<'tcx, ()> {
689689
self.check_abi(abi, exp_abi)?;
690-
if let Some(body) = self.eval_context_mut().lookup_exported_symbol(link_name)? {
690+
if let Some((body, _)) = self.eval_context_mut().lookup_exported_symbol(link_name)? {
691691
throw_machine_stop!(TerminationInfo::SymbolShimClashing {
692692
link_name,
693693
span: body.span.data(),

src/machine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
452452
args: &[OpTy<'tcx, Tag>],
453453
ret: Option<(&PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
454454
unwind: StackPopUnwind,
455-
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
455+
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
456456
ecx.find_mir_or_eval_fn(instance, abi, args, ret, unwind)
457457
}
458458

src/shims/foreign_items.rs

Lines changed: 84 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::{
2+
collections::hash_map::Entry,
23
convert::{TryFrom, TryInto},
34
iter,
45
};
@@ -34,7 +35,7 @@ pub enum EmulateByNameResult<'mir, 'tcx> {
3435
/// Jumping has already been taken care of.
3536
AlreadyJumped,
3637
/// A MIR body has been found for the function
37-
MirBody(&'mir mir::Body<'tcx>),
38+
MirBody(&'mir mir::Body<'tcx>, ty::Instance<'tcx>),
3839
/// The item is not supported.
3940
NotSupported,
4041
}
@@ -135,81 +136,91 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
135136
fn lookup_exported_symbol(
136137
&mut self,
137138
link_name: Symbol,
138-
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
139+
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
139140
let this = self.eval_context_mut();
140141
let tcx = this.tcx.tcx;
141142

142143
// If the result was cached, just return it.
143-
if let Some(instance) = this.machine.exported_symbols_cache.get(&link_name) {
144-
return instance.map(|instance| this.load_mir(instance.def, None)).transpose();
145-
}
146-
147-
// Find it if it was not cached.
148-
let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None;
149-
// `dependency_formats` includes all the transitive informations needed to link a crate,
150-
// which is what we need here since we need to dig out `exported_symbols` from all transitive
151-
// dependencies.
152-
let dependency_formats = tcx.dependency_formats(());
153-
let dependency_format = dependency_formats
154-
.iter()
155-
.find(|(crate_type, _)| *crate_type == CrateType::Executable)
156-
.expect("interpreting a non-executable crate");
157-
for cnum in
158-
iter::once(LOCAL_CRATE).chain(dependency_format.1.iter().enumerate().filter_map(
159-
|(num, &linkage)| (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1)),
160-
))
161-
{
162-
// We can ignore `_export_level` here: we are a Rust crate, and everything is exported
163-
// from a Rust crate.
164-
for &(symbol, _export_level) in tcx.exported_symbols(cnum) {
165-
if let ExportedSymbol::NonGeneric(def_id) = symbol {
166-
let attrs = tcx.codegen_fn_attrs(def_id);
167-
let symbol_name = if let Some(export_name) = attrs.export_name {
168-
export_name
169-
} else if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
170-
tcx.item_name(def_id)
171-
} else {
172-
// Skip over items without an explicitly defined symbol name.
173-
continue;
174-
};
175-
if symbol_name == link_name {
176-
if let Some((original_instance, original_cnum)) = instance_and_crate {
177-
// Make sure we are consistent wrt what is 'first' and 'second'.
178-
let original_span = tcx.def_span(original_instance.def_id()).data();
179-
let span = tcx.def_span(def_id).data();
180-
if original_span < span {
181-
throw_machine_stop!(TerminationInfo::MultipleSymbolDefinitions {
182-
link_name,
183-
first: original_span,
184-
first_crate: tcx.crate_name(original_cnum),
185-
second: span,
186-
second_crate: tcx.crate_name(cnum),
187-
});
144+
// (Cannot use `or_insert` since the code below might have to throw an error.)
145+
let entry = this.machine.exported_symbols_cache.entry(link_name);
146+
let instance = *match entry {
147+
Entry::Occupied(e) => e.into_mut(),
148+
Entry::Vacant(e) => {
149+
// Find it if it was not cached.
150+
let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None;
151+
// `dependency_formats` includes all the transitive informations needed to link a crate,
152+
// which is what we need here since we need to dig out `exported_symbols` from all transitive
153+
// dependencies.
154+
let dependency_formats = tcx.dependency_formats(());
155+
let dependency_format = dependency_formats
156+
.iter()
157+
.find(|(crate_type, _)| *crate_type == CrateType::Executable)
158+
.expect("interpreting a non-executable crate");
159+
for cnum in iter::once(LOCAL_CRATE).chain(
160+
dependency_format.1.iter().enumerate().filter_map(|(num, &linkage)| {
161+
(linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1))
162+
}),
163+
) {
164+
// We can ignore `_export_level` here: we are a Rust crate, and everything is exported
165+
// from a Rust crate.
166+
for &(symbol, _export_level) in tcx.exported_symbols(cnum) {
167+
if let ExportedSymbol::NonGeneric(def_id) = symbol {
168+
let attrs = tcx.codegen_fn_attrs(def_id);
169+
let symbol_name = if let Some(export_name) = attrs.export_name {
170+
export_name
171+
} else if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
172+
tcx.item_name(def_id)
188173
} else {
189-
throw_machine_stop!(TerminationInfo::MultipleSymbolDefinitions {
190-
link_name,
191-
first: span,
192-
first_crate: tcx.crate_name(cnum),
193-
second: original_span,
194-
second_crate: tcx.crate_name(original_cnum),
195-
});
174+
// Skip over items without an explicitly defined symbol name.
175+
continue;
176+
};
177+
if symbol_name == link_name {
178+
if let Some((original_instance, original_cnum)) = instance_and_crate
179+
{
180+
// Make sure we are consistent wrt what is 'first' and 'second'.
181+
let original_span =
182+
tcx.def_span(original_instance.def_id()).data();
183+
let span = tcx.def_span(def_id).data();
184+
if original_span < span {
185+
throw_machine_stop!(
186+
TerminationInfo::MultipleSymbolDefinitions {
187+
link_name,
188+
first: original_span,
189+
first_crate: tcx.crate_name(original_cnum),
190+
second: span,
191+
second_crate: tcx.crate_name(cnum),
192+
}
193+
);
194+
} else {
195+
throw_machine_stop!(
196+
TerminationInfo::MultipleSymbolDefinitions {
197+
link_name,
198+
first: span,
199+
first_crate: tcx.crate_name(cnum),
200+
second: original_span,
201+
second_crate: tcx.crate_name(original_cnum),
202+
}
203+
);
204+
}
205+
}
206+
if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
207+
throw_ub_format!(
208+
"attempt to call an exported symbol that is not defined as a function"
209+
);
210+
}
211+
instance_and_crate = Some((ty::Instance::mono(tcx, def_id), cnum));
196212
}
197213
}
198-
if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
199-
throw_ub_format!(
200-
"attempt to call an exported symbol that is not defined as a function"
201-
);
202-
}
203-
instance_and_crate = Some((ty::Instance::mono(tcx, def_id), cnum));
204214
}
205215
}
216+
217+
e.insert(instance_and_crate.map(|ic| ic.0))
206218
}
219+
};
220+
match instance {
221+
None => Ok(None), // no symbol with this name
222+
Some(instance) => Ok(Some((this.load_mir(instance.def, None)?, instance))),
207223
}
208-
209-
let instance = instance_and_crate.map(|ic| ic.0);
210-
// Cache it and load its MIR, if found.
211-
this.machine.exported_symbols_cache.try_insert(link_name, instance).unwrap();
212-
instance.map(|instance| this.load_mir(instance.def, None)).transpose()
213224
}
214225

215226
/// Emulates calling a foreign item, failing if the item is not supported.
@@ -225,7 +236,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
225236
args: &[OpTy<'tcx, Tag>],
226237
ret: Option<(&PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
227238
unwind: StackPopUnwind,
228-
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
239+
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
229240
let this = self.eval_context_mut();
230241
let attrs = this.tcx.get_attrs(def_id);
231242
let link_name = this
@@ -253,7 +264,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
253264
this.check_abi_and_shim_symbol_clash(abi, Abi::Rust, link_name)?;
254265
let panic_impl_id = tcx.lang_items().panic_impl().unwrap();
255266
let panic_impl_instance = ty::Instance::mono(tcx, panic_impl_id);
256-
return Ok(Some(&*this.load_mir(panic_impl_instance.def, None)?));
267+
return Ok(Some((
268+
&*this.load_mir(panic_impl_instance.def, None)?,
269+
panic_impl_instance,
270+
)));
257271
}
258272
#[rustfmt::skip]
259273
| "exit"
@@ -297,7 +311,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
297311
this.go_to_block(ret);
298312
}
299313
EmulateByNameResult::AlreadyJumped => (),
300-
EmulateByNameResult::MirBody(mir) => return Ok(Some(mir)),
314+
EmulateByNameResult::MirBody(mir, instance) => return Ok(Some((mir, instance))),
301315
EmulateByNameResult::NotSupported => {
302316
if let Some(body) = this.lookup_exported_symbol(link_name)? {
303317
return Ok(Some(body));
@@ -328,11 +342,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
328342

329343
match allocator_kind {
330344
AllocatorKind::Global => {
331-
let body = this
345+
let (body, instance) = this
332346
.lookup_exported_symbol(symbol)?
333347
.expect("symbol should be present if there is a global allocator");
334348

335-
Ok(EmulateByNameResult::MirBody(body))
349+
Ok(EmulateByNameResult::MirBody(body, instance))
336350
}
337351
AllocatorKind::Default => {
338352
default(this)?;

src/shims/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
3030
args: &[OpTy<'tcx, Tag>],
3131
ret: Option<(&PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
3232
unwind: StackPopUnwind,
33-
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
33+
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
3434
let this = self.eval_context_mut();
3535
trace!("eval_fn_call: {:#?}, {:?}", instance, ret.map(|p| p.0));
3636

@@ -54,7 +54,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5454
}
5555

5656
// Otherwise, load the MIR.
57-
Ok(Some(&*this.load_mir(instance.def, None)?))
57+
Ok(Some((&*this.load_mir(instance.def, None)?, instance)))
5858
}
5959

6060
/// Returns `true` if the computation was performed, and `false` if we should just evaluate

0 commit comments

Comments
 (0)