let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Env.into());
for (idx, arg) in argvs.into_iter().enumerate() {
let place = ecx.mplace_field(argvs_place, idx as u64)?;
- ecx.write_scalar(Scalar::Ptr(arg), place.into())?;
+ ecx.write_scalar(arg, place.into())?;
}
ecx.memory
.mark_immutable(argvs_place.ptr.assert_ptr().alloc_id)?;
// Call start function.
ecx.call_function(
start_instance,
- &[main_ptr.into(), argc, argv],
+ &[main_ptr.into(), argc.into(), argv.into()],
Some(ret_place.into()),
StackPopCleanup::None { cleanup: true },
)?;
fn call_function(
&mut self,
f: ty::Instance<'tcx>,
- args: &[Scalar<Tag>],
+ args: &[Immediate<Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
stack_pop: StackPopCleanup,
) -> InterpResult<'tcx> {
let callee_arg = this.local_place(
callee_args.next().expect("callee has fewer arguments than expected")
)?;
- this.write_scalar(*arg, callee_arg)?;
+ this.write_immediate(*arg, callee_arg)?;
}
callee_args.next().expect_none("callee has more arguments than expected");
let malloc = ty::Instance::mono(ecx.tcx.tcx, malloc);
ecx.call_function(
malloc,
- &[size, align],
+ &[size.into(), align.into()],
Some(dest),
// Don't do anything when we are done. The `statement()` function will increment
// the old stack frame's stmt counter to the next statement, which means that when
Ok(match this.machine.env_vars.map.get(name) {
// The offset is used to strip the "{name}=" part of the string.
Some(var_ptr) => {
- Scalar::Ptr(var_ptr.offset(Size::from_bytes(name.len() as u64 + 1), this)?)
+ Scalar::from(var_ptr.offset(Size::from_bytes(name.len() as u64 + 1), this)?)
}
None => Scalar::ptr_null(&*this.tcx),
})
Align::from_bytes(align).unwrap(),
MiriMemoryKind::C.into(),
);
- this.write_scalar(Scalar::Ptr(ptr), ret.into())?;
+ this.write_scalar(ptr, ret.into())?;
}
this.write_null(dest)?;
}
Align::from_bytes(align).unwrap(),
MiriMemoryKind::Rust.into(),
);
- this.write_scalar(Scalar::Ptr(ptr), dest)?;
+ this.write_scalar(ptr, dest)?;
}
"__rust_alloc_zeroed" => {
let size = this.read_scalar(args[0])?.to_machine_usize(this)?;
this.memory
.write_bytes(ptr.into(), iter::repeat(0u8).take(size as usize))
.unwrap();
- this.write_scalar(Scalar::Ptr(ptr), dest)?;
+ this.write_scalar(ptr, dest)?;
}
"__rust_dealloc" => {
let ptr = this.read_scalar(args[0])?.not_undef()?;
align,
MiriMemoryKind::Rust.into(),
)?;
- this.write_scalar(Scalar::Ptr(new_ptr), dest)?;
+ this.write_scalar(new_ptr, dest)?;
}
"syscall" => {
MPlaceTy::dangling(this.layout_of(tcx.mk_unit())?, this).into();
this.call_function(
f_instance,
- &[f_arg],
+ &[f_arg.into()],
Some(ret_place),
// Directly return to caller.
StackPopCleanup::Goto { ret: Some(ret), unwind: None },
match msg {
BoundsCheck { ref index, ref len } => {
+ // Forward to `panic_bounds_check` lang item.
+
// First arg: Caller location.
let location = this.alloc_caller_location_for_span(span)?;
// Second arg: index.
let panic_bounds_check = ty::Instance::mono(this.tcx.tcx, panic_bounds_check);
this.call_function(
panic_bounds_check,
- &[location.ptr, index.not_undef()?, len.not_undef()?],
+ &[location.ptr.into(), index.into(), len.into()],
+ None,
+ StackPopCleanup::Goto { ret: None, unwind },
+ )?;
+ }
+ _ => {
+ // Forward everything else to `panic` lang item.
+
+ // First arg: Message.
+ let msg = msg.description();
+ let msg = this.allocate_str(msg, MiriMemoryKind::Static.into());
+
+ // Second arg: Caller location.
+ let location = this.alloc_caller_location_for_span(span)?;
+
+ // Call the lang item.
+ let panic = this.tcx.lang_items().panic_fn().unwrap();
+ let panic = ty::Instance::mono(this.tcx.tcx, panic);
+ this.call_function(
+ panic,
+ &[msg.to_ref(), location.ptr.into()],
None,
StackPopCleanup::Goto { ret: None, unwind },
)?;
}
- _ => unimplemented!()
}
Ok(())
}
let ret_place = MPlaceTy::dangling(this.layout_of(this.tcx.mk_unit())?, this).into();
this.call_function(
instance,
- &[ptr],
+ &[ptr.into()],
Some(ret_place),
StackPopCleanup::None { cleanup: true },
)?;