Skip to content

Commit b91383b

Browse files
committed
implement proper panicking for other MIR assertions
Requires generalizing the call_function helper to arbitrary Immediate arguments
1 parent 8a36d12 commit b91383b

File tree

7 files changed

+35
-14
lines changed

7 files changed

+35
-14
lines changed

src/eval.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
103103
let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Env.into());
104104
for (idx, arg) in argvs.into_iter().enumerate() {
105105
let place = ecx.mplace_field(argvs_place, idx as u64)?;
106-
ecx.write_scalar(Scalar::Ptr(arg), place.into())?;
106+
ecx.write_scalar(arg, place.into())?;
107107
}
108108
ecx.memory
109109
.mark_immutable(argvs_place.ptr.assert_ptr().alloc_id)?;
@@ -149,7 +149,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
149149
// Call start function.
150150
ecx.call_function(
151151
start_instance,
152-
&[main_ptr.into(), argc, argv],
152+
&[main_ptr.into(), argc.into(), argv.into()],
153153
Some(ret_place.into()),
154154
StackPopCleanup::None { cleanup: true },
155155
)?;

src/helpers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
124124
fn call_function(
125125
&mut self,
126126
f: ty::Instance<'tcx>,
127-
args: &[Scalar<Tag>],
127+
args: &[Immediate<Tag>],
128128
dest: Option<PlaceTy<'tcx, Tag>>,
129129
stack_pop: StackPopCleanup,
130130
) -> InterpResult<'tcx> {
@@ -146,7 +146,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
146146
let callee_arg = this.local_place(
147147
callee_args.next().expect("callee has fewer arguments than expected")
148148
)?;
149-
this.write_scalar(*arg, callee_arg)?;
149+
this.write_immediate(*arg, callee_arg)?;
150150
}
151151
callee_args.next().expect_none("callee has more arguments than expected");
152152

src/machine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
253253
let malloc = ty::Instance::mono(ecx.tcx.tcx, malloc);
254254
ecx.call_function(
255255
malloc,
256-
&[size, align],
256+
&[size.into(), align.into()],
257257
Some(dest),
258258
// Don't do anything when we are done. The `statement()` function will increment
259259
// the old stack frame's stmt counter to the next statement, which means that when

src/shims/env.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5757
Ok(match this.machine.env_vars.map.get(name) {
5858
// The offset is used to strip the "{name}=" part of the string.
5959
Some(var_ptr) => {
60-
Scalar::Ptr(var_ptr.offset(Size::from_bytes(name.len() as u64 + 1), this)?)
60+
Scalar::from(var_ptr.offset(Size::from_bytes(name.len() as u64 + 1), this)?)
6161
}
6262
None => Scalar::ptr_null(&*this.tcx),
6363
})

src/shims/foreign_items.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
205205
Align::from_bytes(align).unwrap(),
206206
MiriMemoryKind::C.into(),
207207
);
208-
this.write_scalar(Scalar::Ptr(ptr), ret.into())?;
208+
this.write_scalar(ptr, ret.into())?;
209209
}
210210
this.write_null(dest)?;
211211
}
@@ -234,7 +234,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
234234
Align::from_bytes(align).unwrap(),
235235
MiriMemoryKind::Rust.into(),
236236
);
237-
this.write_scalar(Scalar::Ptr(ptr), dest)?;
237+
this.write_scalar(ptr, dest)?;
238238
}
239239
"__rust_alloc_zeroed" => {
240240
let size = this.read_scalar(args[0])?.to_machine_usize(this)?;
@@ -254,7 +254,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
254254
this.memory
255255
.write_bytes(ptr.into(), iter::repeat(0u8).take(size as usize))
256256
.unwrap();
257-
this.write_scalar(Scalar::Ptr(ptr), dest)?;
257+
this.write_scalar(ptr, dest)?;
258258
}
259259
"__rust_dealloc" => {
260260
let ptr = this.read_scalar(args[0])?.not_undef()?;
@@ -295,7 +295,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
295295
align,
296296
MiriMemoryKind::Rust.into(),
297297
)?;
298-
this.write_scalar(Scalar::Ptr(new_ptr), dest)?;
298+
this.write_scalar(new_ptr, dest)?;
299299
}
300300

301301
"syscall" => {

src/shims/panic.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8686
MPlaceTy::dangling(this.layout_of(tcx.mk_unit())?, this).into();
8787
this.call_function(
8888
f_instance,
89-
&[f_arg],
89+
&[f_arg.into()],
9090
Some(ret_place),
9191
// Directly return to caller.
9292
StackPopCleanup::Goto { ret: Some(ret), unwind: None },
@@ -163,6 +163,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
163163

164164
match msg {
165165
BoundsCheck { ref index, ref len } => {
166+
// Forward to `panic_bounds_check` lang item.
167+
166168
// First arg: Caller location.
167169
let location = this.alloc_caller_location_for_span(span)?;
168170
// Second arg: index.
@@ -175,12 +177,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
175177
let panic_bounds_check = ty::Instance::mono(this.tcx.tcx, panic_bounds_check);
176178
this.call_function(
177179
panic_bounds_check,
178-
&[location.ptr, index.not_undef()?, len.not_undef()?],
180+
&[location.ptr.into(), index.into(), len.into()],
181+
None,
182+
StackPopCleanup::Goto { ret: None, unwind },
183+
)?;
184+
}
185+
_ => {
186+
// Forward everything else to `panic` lang item.
187+
188+
// First arg: Message.
189+
let msg = msg.description();
190+
let msg = this.allocate_str(msg, MiriMemoryKind::Static.into());
191+
192+
// Second arg: Caller location.
193+
let location = this.alloc_caller_location_for_span(span)?;
194+
195+
// Call the lang item.
196+
let panic = this.tcx.lang_items().panic_fn().unwrap();
197+
let panic = ty::Instance::mono(this.tcx.tcx, panic);
198+
this.call_function(
199+
panic,
200+
&[msg.to_ref(), location.ptr.into()],
179201
None,
180202
StackPopCleanup::Goto { ret: None, unwind },
181203
)?;
182204
}
183-
_ => unimplemented!()
184205
}
185206
Ok(())
186207
}

src/shims/tls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
150150
let ret_place = MPlaceTy::dangling(this.layout_of(this.tcx.mk_unit())?, this).into();
151151
this.call_function(
152152
instance,
153-
&[ptr],
153+
&[ptr.into()],
154154
Some(ret_place),
155155
StackPopCleanup::None { cleanup: true },
156156
)?;

0 commit comments

Comments
 (0)