@@ -127,9 +127,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
127
127
let tcx = & { this. tcx . tcx } ;
128
128
129
129
// First: functions that diverge.
130
- let ( dest, ret) = match link_name {
131
- // Note that this matches calls to the *foreign* item `__rust_start_panic* -
132
- // that is, calls to `extern "Rust" { fn __rust_start_panic(...) }`.
130
+ let ( dest, ret) = match ret {
131
+ None => match link_name {
132
+ // This matches calls to the foreign item `panic_impl`.
133
+ // The implementation is provided by the function with the `#[panic_handler]` attribute.
134
+ "panic_impl" => {
135
+ let panic_impl_id = this. tcx . lang_items ( ) . panic_impl ( ) . unwrap ( ) ;
136
+ let panic_impl_instance = ty:: Instance :: mono ( * this. tcx , panic_impl_id) ;
137
+ return Ok ( Some ( & * this. load_mir ( panic_impl_instance. def , None ) ?) ) ;
138
+ }
139
+ | "exit"
140
+ | "ExitProcess"
141
+ => {
142
+ // it's really u32 for ExitProcess, but we have to put it into the `Exit` variant anyway
143
+ let code = this. read_scalar ( args[ 0 ] ) ?. to_i32 ( ) ?;
144
+ throw_machine_stop ! ( TerminationInfo :: Exit ( code. into( ) ) ) ;
145
+ }
146
+ _ => throw_unsup_format ! ( "can't call (diverging) foreign function: {}" , link_name) ,
147
+ } ,
148
+ Some ( p) => p,
149
+ } ;
150
+
151
+ // Second: some functions that we forward to MIR implementations.
152
+ match link_name {
153
+ // This matches calls to the *foreign* item `__rust_start_panic*, that is,
154
+ // calls to `extern "Rust" { fn __rust_start_panic(...) }`.
133
155
// We forward this to the underlying *implementation* in the panic runtime crate.
134
156
// Normally, this will be either `libpanic_unwind` or `libpanic_abort`, but it could
135
157
// also be a custom user-provided implementation via `#![feature(panic_runtime)]`
@@ -145,31 +167,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
145
167
this. resolve_path ( & [ & * panic_runtime. as_str ( ) , "__rust_start_panic" ] ) ?;
146
168
return Ok ( Some ( & * this. load_mir ( start_panic_instance. def , None ) ?) ) ;
147
169
}
148
- // Similarly, we forward calls to the `panic_impl` foreign item to its implementation.
149
- // The implementation is provided by the function with the `#[panic_handler]` attribute.
150
- "panic_impl" => {
151
- let panic_impl_id = this. tcx . lang_items ( ) . panic_impl ( ) . unwrap ( ) ;
152
- let panic_impl_instance = ty:: Instance :: mono ( * this. tcx , panic_impl_id) ;
153
- return Ok ( Some ( & * this. load_mir ( panic_impl_instance. def , None ) ?) ) ;
154
- }
155
-
156
- | "exit"
157
- | "ExitProcess"
158
- => {
159
- // it's really u32 for ExitProcess, but we have to put it into the `Exit` variant anyway
160
- let code = this. read_scalar ( args[ 0 ] ) ?. to_i32 ( ) ?;
161
- throw_machine_stop ! ( TerminationInfo :: Exit ( code. into( ) ) ) ;
162
- }
163
- _ => {
164
- if let Some ( p) = ret {
165
- p
166
- } else {
167
- throw_unsup_format ! ( "can't call (diverging) foreign function: {}" , link_name) ;
168
- }
169
- }
170
- } ;
170
+ _ => { }
171
+ }
171
172
172
- // Next : functions that return.
173
+ // Third : functions that return.
173
174
if this. emulate_foreign_item_by_name ( link_name, args, dest, ret) ? {
174
175
this. dump_place ( * dest) ;
175
176
this. go_to_block ( ret) ;
0 commit comments