summaryrefslogtreecommitdiffstats
path: root/library/panic_unwind/src/miri.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/panic_unwind/src/miri.rs')
-rw-r--r--library/panic_unwind/src/miri.rs25
1 files changed, 25 insertions, 0 deletions
diff --git a/library/panic_unwind/src/miri.rs b/library/panic_unwind/src/miri.rs
new file mode 100644
index 000000000..d941b73b5
--- /dev/null
+++ b/library/panic_unwind/src/miri.rs
@@ -0,0 +1,25 @@
+//! Unwinding panics for Miri.
+use alloc::boxed::Box;
+use core::any::Any;
+
+// The type of the payload that the Miri engine propagates through unwinding for us.
+// Must be pointer-sized.
+type Payload = Box<Box<dyn Any + Send>>;
+
+extern "Rust" {
+ /// Miri-provided extern function to begin unwinding.
+ fn miri_start_panic(payload: *mut u8) -> !;
+}
+
+pub unsafe fn panic(payload: Box<dyn Any + Send>) -> u32 {
+ // The payload we pass to `miri_start_panic` will be exactly the argument we get
+ // in `cleanup` below. So we just box it up once, to get something pointer-sized.
+ let payload_box: Payload = Box::new(payload);
+ miri_start_panic(Box::into_raw(payload_box) as *mut u8)
+}
+
+pub unsafe fn cleanup(payload_box: *mut u8) -> Box<dyn Any + Send> {
+ // Recover the underlying `Box`.
+ let payload_box: Payload = Box::from_raw(payload_box as *mut _);
+ *payload_box
+}