};
// Strip linker suffixes (seen on 32-bit macOS).
let link_name = link_name.trim_end_matches("$UNIX2003");
- let tcx = &{ this.tcx.tcx };
+ let tcx = this.tcx.tcx;
// First: functions that diverge.
let (dest, ret) = match ret {
// The implementation is provided by the function with the `#[panic_handler]` attribute.
"panic_impl" => {
this.check_panic_supported()?;
- let panic_impl_id = this.tcx.lang_items().panic_impl().unwrap();
- let panic_impl_instance = ty::Instance::mono(*this.tcx, panic_impl_id);
+ let panic_impl_id = tcx.lang_items().panic_impl().unwrap();
+ let panic_impl_instance = ty::Instance::mono(tcx, panic_impl_id);
return Ok(Some(&*this.load_mir(panic_impl_instance.def, None)?));
}
| "exit"
ret: mir::BasicBlock,
) -> InterpResult<'tcx, bool> {
let this = self.eval_context_mut();
- let tcx = &{ this.tcx.tcx };
match link_name {
// Environment related shims
"write" => {
let fd = this.read_scalar(args[0])?.to_i32()?;
let buf = this.read_scalar(args[1])?.not_undef()?;
- let n = this.read_scalar(args[2])?.to_machine_usize(tcx)?;
+ let n = this.read_scalar(args[2])?.to_machine_usize(this)?;
trace!("Called write({:?}, {:?}, {:?})", fd, buf, n);
let result = if fd == 1 || fd == 2 {
// stdout/stderr
}
"pthread_getspecific" => {
let key = this.force_bits(this.read_scalar(args[0])?.not_undef()?, args[0].layout.size)?;
- let ptr = this.machine.tls.load_tls(key, tcx)?;
+ let ptr = this.machine.tls.load_tls(key, this)?;
this.write_scalar(ptr, dest)?;
}
"pthread_setspecific" => {
_ret: mir::BasicBlock,
) -> InterpResult<'tcx, bool> {
let this = self.eval_context_mut();
- let tcx = &{ this.tcx.tcx };
match link_name {
// Windows API stubs.
}
"TlsGetValue" => {
let key = u128::from(this.read_scalar(args[0])?.to_u32()?);
- let ptr = this.machine.tls.load_tls(key, tcx)?;
+ let ptr = this.machine.tls.load_tls(key, this)?;
this.write_scalar(ptr, dest)?;
}
"TlsSetValue" => {
if this.emulate_intrinsic(span, instance, args, ret)? {
return Ok(());
}
- let tcx = &{ this.tcx.tcx };
let substs = instance.substs;
// All these intrinsics take raw pointers, so if we access memory directly
// (as opposed to through a place), we have to remember to erase any tag
// that might still hang around!
- let intrinsic_name = &*tcx.item_name(instance.def_id()).as_str();
+ let intrinsic_name = &*this.tcx.item_name(instance.def_id()).as_str();
// First handle intrinsics without return place.
let (dest, ret) = match ret {
}
pub fn load_tls(
- &mut self,
+ &self,
key: TlsKey,
cx: &impl HasDataLayout,
) -> InterpResult<'tcx, Scalar<Tag>> {
Ok(())
}
- /// Returns a dtor, its argument and its index, if one is supposed to run
+ /// Returns a dtor, its argument and its index, if one is supposed to run.
+ /// `key` is the last dtors that was run; we return the *next* one after that.
///
/// An optional destructor function may be associated with each key value.
/// At thread exit, if a key value has a non-NULL destructor pointer,
// step until out of stackframes
this.run()?;
+ // Fetch next dtor after `key`.
dtor = match this.machine.tls.fetch_tls_dtor(Some(key)) {
dtor @ Some(_) => dtor,
+ // We ran each dtor once, start over from the beginning.
None => this.machine.tls.fetch_tls_dtor(None),
};
}