@@ -11,14 +11,14 @@ use rustc_abi::ExternAbi;
11
11
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
12
12
use rustc_hir:: def:: Namespace ;
13
13
use rustc_hir:: def_id:: DefId ;
14
- use rustc_middle:: ty:: layout:: LayoutCx ;
14
+ use rustc_middle:: ty:: layout:: { HasTyCtxt , HasTypingEnv , LayoutCx } ;
15
15
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
16
16
use rustc_session:: config:: EntryFnType ;
17
17
18
18
use crate :: concurrency:: GenmcCtx ;
19
19
use crate :: concurrency:: thread:: TlsAllocAction ;
20
20
use crate :: diagnostics:: report_leaks;
21
- use crate :: shims:: tls;
21
+ use crate :: shims:: { ctor , tls} ;
22
22
use crate :: * ;
23
23
24
24
#[ derive( Copy , Clone , Debug ) ]
@@ -216,9 +216,15 @@ impl Default for MiriConfig {
216
216
}
217
217
218
218
/// The state of the main thread. Implementation detail of `on_main_stack_empty`.
219
- #[ derive( Default , Debug ) ]
219
+ #[ derive( Debug ) ]
220
220
enum MainThreadState < ' tcx > {
221
- #[ default]
221
+ GlobalCtors {
222
+ ctor_state : ctor:: GlobalCtorState < ' tcx > ,
223
+ entry_id : DefId ,
224
+ entry_type : MiriEntryFnType ,
225
+ argc : ImmTy < ' tcx > ,
226
+ argv : ImmTy < ' tcx > ,
227
+ } ,
222
228
Running ,
223
229
TlsDtors ( tls:: TlsDtorsState < ' tcx > ) ,
224
230
Yield {
@@ -234,6 +240,15 @@ impl<'tcx> MainThreadState<'tcx> {
234
240
) -> InterpResult < ' tcx , Poll < ( ) > > {
235
241
use MainThreadState :: * ;
236
242
match self {
243
+ GlobalCtors { ctor_state, entry_id, entry_type, argc, argv } => {
244
+ match ctor_state. on_stack_empty ( this) ? {
245
+ Poll :: Pending => { } // just keep going
246
+ Poll :: Ready ( ( ) ) => {
247
+ call_main ( this, * entry_id, * entry_type, argc. clone ( ) , argv. clone ( ) ) ?;
248
+ * self = Running ;
249
+ }
250
+ }
251
+ }
237
252
Running => {
238
253
* self = TlsDtors ( Default :: default ( ) ) ;
239
254
}
@@ -309,26 +324,6 @@ pub fn create_ecx<'tcx>(
309
324
MiriMachine :: new ( config, layout_cx, genmc_ctx) ,
310
325
) ;
311
326
312
- // Some parts of initialization require a full `InterpCx`.
313
- MiriMachine :: late_init ( & mut ecx, config, {
314
- let mut state = MainThreadState :: default ( ) ;
315
- // Cannot capture anything GC-relevant here.
316
- Box :: new ( move |m| state. on_main_stack_empty ( m) )
317
- } ) ?;
318
-
319
- // Make sure we have MIR. We check MIR for some stable monomorphic function in libcore.
320
- let sentinel =
321
- helpers:: try_resolve_path ( tcx, & [ "core" , "ascii" , "escape_default" ] , Namespace :: ValueNS ) ;
322
- if !matches ! ( sentinel, Some ( s) if tcx. is_mir_available( s. def. def_id( ) ) ) {
323
- tcx. dcx ( ) . fatal (
324
- "the current sysroot was built without `-Zalways-encode-mir`, or libcore seems missing. \
325
- Use `cargo miri setup` to prepare a sysroot that is suitable for Miri."
326
- ) ;
327
- }
328
-
329
- // Setup first stack frame.
330
- let entry_instance = ty:: Instance :: mono ( tcx, entry_id) ;
331
-
332
327
// First argument is constructed later, because it's skipped for `miri_start.`
333
328
334
329
// Second argument (argc): length of `config.args`.
@@ -395,11 +390,51 @@ pub fn create_ecx<'tcx>(
395
390
ImmTy :: from_immediate ( imm, layout)
396
391
} ;
397
392
393
+ // Some parts of initialization require a full `InterpCx`.
394
+ MiriMachine :: late_init ( & mut ecx, config, {
395
+ let mut state = MainThreadState :: GlobalCtors {
396
+ entry_id,
397
+ entry_type,
398
+ argc,
399
+ argv,
400
+ ctor_state : ctor:: GlobalCtorState :: default ( ) ,
401
+ } ;
402
+
403
+ // Cannot capture anything GC-relevant here.
404
+ Box :: new ( move |m| state. on_main_stack_empty ( m) )
405
+ } ) ?;
406
+
407
+ // Make sure we have MIR. We check MIR for some stable monomorphic function in libcore.
408
+ let sentinel =
409
+ helpers:: try_resolve_path ( tcx, & [ "core" , "ascii" , "escape_default" ] , Namespace :: ValueNS ) ;
410
+ if !matches ! ( sentinel, Some ( s) if tcx. is_mir_available( s. def. def_id( ) ) ) {
411
+ tcx. dcx ( ) . fatal (
412
+ "the current sysroot was built without `-Zalways-encode-mir`, or libcore seems missing. \
413
+ Use `cargo miri setup` to prepare a sysroot that is suitable for Miri."
414
+ ) ;
415
+ }
416
+
417
+ interp_ok ( ecx)
418
+ }
419
+
420
+ // Call the entry function.
421
+ fn call_main < ' tcx > (
422
+ ecx : & mut MiriInterpCx < ' tcx > ,
423
+ entry_id : DefId ,
424
+ entry_type : MiriEntryFnType ,
425
+ argc : ImmTy < ' tcx > ,
426
+ argv : ImmTy < ' tcx > ,
427
+ ) -> InterpResult < ' tcx , ( ) > {
428
+ let tcx = ecx. tcx ( ) ;
429
+
430
+ // Setup first stack frame.
431
+ let entry_instance = ty:: Instance :: mono ( tcx, entry_id) ;
432
+
398
433
// Return place (in static memory so that it does not count as leak).
399
434
let ret_place = ecx. allocate ( ecx. machine . layouts . isize , MiriMemoryKind :: Machine . into ( ) ) ?;
400
435
ecx. machine . main_fn_ret_place = Some ( ret_place. clone ( ) ) ;
401
- // Call start function.
402
436
437
+ // Call start function.
403
438
match entry_type {
404
439
MiriEntryFnType :: Rustc ( EntryFnType :: Main { .. } ) => {
405
440
let start_id = tcx. lang_items ( ) . start_fn ( ) . unwrap_or_else ( || {
@@ -409,7 +444,7 @@ pub fn create_ecx<'tcx>(
409
444
let main_ret_ty = main_ret_ty. no_bound_vars ( ) . unwrap ( ) ;
410
445
let start_instance = ty:: Instance :: try_resolve (
411
446
tcx,
412
- typing_env,
447
+ ecx . typing_env ( ) ,
413
448
start_id,
414
449
tcx. mk_args ( & [ ty:: GenericArg :: from ( main_ret_ty) ] ) ,
415
450
)
@@ -427,7 +462,7 @@ pub fn create_ecx<'tcx>(
427
462
ExternAbi :: Rust ,
428
463
& [
429
464
ImmTy :: from_scalar (
430
- Scalar :: from_pointer ( main_ptr, & ecx) ,
465
+ Scalar :: from_pointer ( main_ptr, ecx) ,
431
466
// FIXME use a proper fn ptr type
432
467
ecx. machine . layouts . const_raw_ptr ,
433
468
) ,
@@ -450,7 +485,7 @@ pub fn create_ecx<'tcx>(
450
485
}
451
486
}
452
487
453
- interp_ok ( ecx )
488
+ interp_ok ( ( ) )
454
489
}
455
490
456
491
/// Evaluates the entry function specified by `entry_id`.
0 commit comments