@@ -49,49 +49,50 @@ The `extract` function converts the `panic_handler` attribute to a `panic_impl`
49
49
50
50
Now, we have a matching ` panic_handler ` lang item in the ` libstd ` . This function goes
51
51
through the same process as the ` extern { fn panic_impl } ` definition in ` libcore ` , ending
52
- up with a symbol name of ` rust_begin_unwind ` . At link time, the symbol refernce in ` libcore `
52
+ up with a symbol name of ` rust_begin_unwind ` . At link time, the symbol reference in ` libcore `
53
53
will be resolved to the definition of ` libstd ` (the function called ` begin_panic_handler ` in the
54
54
Rust source).
55
55
56
56
Thus, control flow will pass from libcore to std at runtime. This allows panics from ` libcore `
57
- to go through the same infratructure that other panics use (panic hooks, unwinding, etc)
57
+ to go through the same infrastructure that other panics use (panic hooks, unwinding, etc)
58
58
59
59
##### libstd implementation of panic!
60
60
61
- This is where the actual panic-related logic begins. In ` src/libstd/pancking .rs ` ,
61
+ This is where the actual panic-related logic begins. In ` src/libstd/panicking .rs ` ,
62
62
control passes to ` rust_panic_with_hook ` . This method is responsible
63
63
for invoking the global panic hook, and checking for double panics. Finally,
64
- we call ``` __rust_start_panic `` ` , which is provided by the panic runtime.
64
+ we call ` __rust_start_panic ` , which is provided by the panic runtime.
65
65
66
- The call to ``` __rust_start_panic ``` is very weird - it is passed a ``` *mut &mut dyn BoxMeUp `` ` ,
66
+ The call to ` __rust_start_panic ` is very weird - it is passed a ` *mut &mut dyn BoxMeUp ` ,
67
67
converted to an ` usize ` . Let's break this type down:
68
68
69
69
1 . ` BoxMeUp ` is an internal trait. It is implemented for ` PanicPayload `
70
70
(a wrapper around the user-supplied payload type), and has a method
71
- ``` fn box_me_up(&mut self) -> *mut (dyn Any + Send) ``` .
72
- This method takes the user-provided payload (` T: Any + Send ` ), boxes it, and convertes the box to a raw pointer.
71
+ ` fn box_me_up(&mut self) -> *mut (dyn Any + Send) ` .
72
+ This method takes the user-provided payload (` T: Any + Send ` ),
73
+ boxes it, and converts the box to a raw pointer.
73
74
74
- 2 . When we call ``` __rust_start_panic `` ` , we have an ` &mut dyn BoxMeUp ` .
75
+ 2 . When we call ` __rust_start_panic ` , we have an ` &mut dyn BoxMeUp ` .
75
76
However, this is a fat pointer (twice the size of a ` usize ` ).
76
77
To pass this to the panic runtime across an FFI boundary, we take a mutable
77
78
reference * to this mutable reference* (` &mut &mut dyn BoxMeUp ` ), and convert it to a raw pointer
78
79
(` *mut &mut dyn BoxMeUp ` ). The outer raw pointer is a thin pointer, since it points to a ` Sized `
79
80
type (a mutable reference). Therefore, we can convert this thin pointer into a ` usize ` , which
80
81
is suitable for passing across an FFI boundary.
81
82
82
- Finally, we call ``` __rust_start_panic `` ` with this ` usize ` . We have now entered the panic runtime.
83
+ Finally, we call ` __rust_start_panic ` with this ` usize ` . We have now entered the panic runtime.
83
84
84
85
#### Step 2: The panic runtime
85
86
86
87
Rust provides two panic runtimes: ` libpanic_abort ` and ` libpanic_unwind ` . The user chooses
87
88
between them at build time via their ` Cargo.toml `
88
89
89
- ` libpanic_abort ` is extremely simple: its implementation of ``` __rust_start_panic `` ` just aborts,
90
+ ` libpanic_abort ` is extremely simple: its implementation of ` __rust_start_panic ` just aborts,
90
91
as you would expect.
91
92
92
93
` libpanic_unwind ` is the more interesting case.
93
94
94
- In its implementation of ``` __rust_start_panic `` ` , we take the ` usize ` , convert
95
+ In its implementation of ` __rust_start_panic ` , we take the ` usize ` , convert
95
96
it back to a ` *mut &mut dyn BoxMeUp ` , dereference it, and call ` box_me_up `
96
97
on the ` &mut dyn BoxMeUp ` . At this point, we have a raw pointer to the payload
97
98
itself (a ` *mut (dyn Send + Any) ` ): that is, a raw pointer to the actual value
0 commit comments