Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update uses of renamed BoxMeUp to PanicPayload #1878

Merged
merged 1 commit into from
Jan 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/panic-implementation.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,22 @@ control passes to `rust_panic_with_hook`. This method is responsible
for invoking the global panic hook, and checking for double panics. Finally,
we call `__rust_start_panic`, which is provided by the panic runtime.

The call to `__rust_start_panic` is very weird - it is passed a `*mut &mut dyn BoxMeUp`,
The call to `__rust_start_panic` is very weird - it is passed a `*mut &mut dyn PanicPayload`,
converted to an `usize`. Let's break this type down:

1. `BoxMeUp` is an internal trait. It is implemented for `PanicPayload`
1. `PanicPayload` is an internal trait. It is implemented for `PanicPayload`
(a wrapper around the user-supplied payload type), and has a method
`fn box_me_up(&mut self) -> *mut (dyn Any + Send)`.
`fn take_box(&mut self) -> *mut (dyn Any + Send)`.
This method takes the user-provided payload (`T: Any + Send`),
boxes it, and converts the box to a raw pointer.

2. When we call `__rust_start_panic`, we have an `&mut dyn BoxMeUp`.
2. When we call `__rust_start_panic`, we have an `&mut dyn PanicPayload`.
However, this is a fat pointer (twice the size of a `usize`).
To pass this to the panic runtime across an FFI boundary, we take a mutable
reference *to this mutable reference* (`&mut &mut dyn BoxMeUp`), and convert it to a raw pointer
(`*mut &mut dyn BoxMeUp`). The outer raw pointer is a thin pointer, since it points to a `Sized`
type (a mutable reference). Therefore, we can convert this thin pointer into a `usize`, which
is suitable for passing across an FFI boundary.
reference *to this mutable reference* (`&mut &mut dyn PanicPayload`), and convert it to a raw
pointer (`*mut &mut dyn PanicPayload`). The outer raw pointer is a thin pointer, since it points to
a `Sized` type (a mutable reference). Therefore, we can convert this thin pointer into a `usize`,
which is suitable for passing across an FFI boundary.

Finally, we call `__rust_start_panic` with this `usize`. We have now entered the panic runtime.

Expand All @@ -96,8 +96,8 @@ as you would expect.
`panic_unwind` is the more interesting case.

In its implementation of `__rust_start_panic`, we take the `usize`, convert
it back to a `*mut &mut dyn BoxMeUp`, dereference it, and call `box_me_up`
on the `&mut dyn BoxMeUp`. At this point, we have a raw pointer to the payload
it back to a `*mut &mut dyn PanicPayload`, dereference it, and call `take_box`
on the `&mut dyn PanicPayload`. At this point, we have a raw pointer to the payload
itself (a `*mut (dyn Send + Any)`): that is, a raw pointer to the actual value
provided by the user who called `panic!`.

Expand Down