start_instance,
Abi::Rust,
&[Scalar::from_pointer(main_ptr, &ecx).into(), argc.into(), argv],
- &ret_place.into(),
+ Some(&ret_place.into()),
StackPopCleanup::Root { cleanup: true },
)?;
}
entry_instance,
Abi::Rust,
&[argc.into(), argv],
- &ret_place.into(),
+ Some(&ret_place.into()),
StackPopCleanup::Root { cleanup: true },
)?;
}
/// Call a function: Push the stack frame and pass the arguments.
/// For now, arguments must be scalars (so that the caller does not have to know the layout).
+ ///
+ /// If you do not provie a return place, a dangling zero-sized place will be created
+ /// for your convenience.
fn call_function(
&mut self,
f: ty::Instance<'tcx>,
caller_abi: Abi,
args: &[Immediate<Tag>],
- dest: &PlaceTy<'tcx, Tag>,
+ dest: Option<&PlaceTy<'tcx, Tag>>,
stack_pop: StackPopCleanup,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
// Push frame.
let mir = this.load_mir(f.def, None)?;
- this.push_stack_frame(f, mir, dest, stack_pop)?;
+ let dest = match dest {
+ Some(dest) => *dest,
+ None => MPlaceTy::dangling(this.layout_of(mir.return_ty())?).into(),
+ };
+ this.push_stack_frame(f, mir, &dest, stack_pop)?;
// Initialize arguments.
let mut callee_args = this.frame().body.args_iter();
// Now we make a function call, and pass `data` as first and only argument.
let f_instance = this.get_ptr_fn(try_fn)?.as_instance()?;
trace!("try_fn: {:?}", f_instance);
- let ret_place = MPlaceTy::dangling(this.machine.layouts.unit).into();
this.call_function(
f_instance,
Abi::Rust,
&[data.into()],
- &ret_place,
+ None,
// Directly return to caller.
StackPopCleanup::Goto { ret: Some(ret), unwind: StackPopUnwind::Skip },
)?;
let f_instance =
this.get_ptr_fn(this.scalar_to_ptr(catch_unwind.catch_fn)?)?.as_instance()?;
trace!("catch_fn: {:?}", f_instance);
- let ret_place = MPlaceTy::dangling(this.machine.layouts.unit).into();
this.call_function(
f_instance,
Abi::Rust,
&[catch_unwind.data.into(), payload.into()],
- &ret_place,
+ None,
// Directly return to caller of `try`.
StackPopCleanup::Goto { ret: Some(catch_unwind.ret), unwind: StackPopUnwind::Skip },
)?;
panic,
Abi::Rust,
&[msg.to_ref(this)],
- &MPlaceTy::dangling(this.machine.layouts.unit).into(),
+ None,
StackPopCleanup::Goto { ret: None, unwind },
)
}
panic_bounds_check,
Abi::Rust,
&[index.into(), len.into()],
- &MPlaceTy::dangling(this.machine.layouts.unit).into(),
+ None,
StackPopCleanup::Goto {
ret: None,
unwind: match unwind {
// The signature of this function is `unsafe extern "system" fn(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID)`.
let reason = this.eval_path_scalar(&["std", "sys", "windows", "c", "DLL_THREAD_DETACH"])?;
- let ret_place = MPlaceTy::dangling(this.machine.layouts.unit).into();
this.call_function(
thread_callback,
Abi::System { unwind: false },
&[Scalar::null_ptr(this).into(), reason.into(), Scalar::null_ptr(this).into()],
- &ret_place,
+ None,
StackPopCleanup::Root { cleanup: true },
)?;
if let Some((instance, data)) = this.machine.tls.macos_thread_dtors.remove(&thread_id) {
trace!("Running macos dtor {:?} on {:?} at {:?}", instance, data, thread_id);
- let ret_place = MPlaceTy::dangling(this.machine.layouts.unit).into();
this.call_function(
instance,
Abi::C { unwind: false },
&[data.into()],
- &ret_place,
+ None,
StackPopCleanup::Root { cleanup: true },
)?;
"data can't be NULL when dtor is called!"
);
- let ret_place = MPlaceTy::dangling(this.machine.layouts.unit).into();
this.call_function(
instance,
Abi::C { unwind: false },
&[ptr.into()],
- &ret_place,
+ None,
StackPopCleanup::Root { cleanup: true },
)?;
instance,
Abi::C { unwind: false },
&[*func_arg],
- &ret_place.into(),
+ Some(&ret_place.into()),
StackPopCleanup::Root { cleanup: true },
)?;