@@ -11,14 +11,14 @@ use rustc_abi::ExternAbi;
1111use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1212use rustc_hir:: def:: Namespace ;
1313use rustc_hir:: def_id:: DefId ;
14- use rustc_middle:: ty:: layout:: LayoutCx ;
14+ use rustc_middle:: ty:: layout:: { HasTyCtxt , HasTypingEnv , LayoutCx } ;
1515use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1616use rustc_session:: config:: EntryFnType ;
1717
1818use crate :: concurrency:: GenmcCtx ;
1919use crate :: concurrency:: thread:: TlsAllocAction ;
2020use crate :: diagnostics:: report_leaks;
21- use crate :: shims:: tls;
21+ use crate :: shims:: { ctor , tls} ;
2222use crate :: * ;
2323
2424#[ derive( Copy , Clone , Debug ) ]
@@ -216,9 +216,15 @@ impl Default for MiriConfig {
216216}
217217
218218/// The state of the main thread. Implementation detail of `on_main_stack_empty`.
219- #[ derive( Default , Debug ) ]
219+ #[ derive( Debug ) ]
220220enum 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+ } ,
222228 Running ,
223229 TlsDtors ( tls:: TlsDtorsState < ' tcx > ) ,
224230 Yield {
@@ -234,6 +240,15 @@ impl<'tcx> MainThreadState<'tcx> {
234240 ) -> InterpResult < ' tcx , Poll < ( ) > > {
235241 use MainThreadState :: * ;
236242 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+ }
237252 Running => {
238253 * self = TlsDtors ( Default :: default ( ) ) ;
239254 }
@@ -309,26 +324,6 @@ pub fn create_ecx<'tcx>(
309324 MiriMachine :: new ( config, layout_cx, genmc_ctx) ,
310325 ) ;
311326
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-
332327 // First argument is constructed later, because it's skipped for `miri_start.`
333328
334329 // Second argument (argc): length of `config.args`.
@@ -395,11 +390,51 @@ pub fn create_ecx<'tcx>(
395390 ImmTy :: from_immediate ( imm, layout)
396391 } ;
397392
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+
398433 // Return place (in static memory so that it does not count as leak).
399434 let ret_place = ecx. allocate ( ecx. machine . layouts . isize , MiriMemoryKind :: Machine . into ( ) ) ?;
400435 ecx. machine . main_fn_ret_place = Some ( ret_place. clone ( ) ) ;
401- // Call start function.
402436
437+ // Call start function.
403438 match entry_type {
404439 MiriEntryFnType :: Rustc ( EntryFnType :: Main { .. } ) => {
405440 let start_id = tcx. lang_items ( ) . start_fn ( ) . unwrap_or_else ( || {
@@ -409,7 +444,7 @@ pub fn create_ecx<'tcx>(
409444 let main_ret_ty = main_ret_ty. no_bound_vars ( ) . unwrap ( ) ;
410445 let start_instance = ty:: Instance :: try_resolve (
411446 tcx,
412- typing_env,
447+ ecx . typing_env ( ) ,
413448 start_id,
414449 tcx. mk_args ( & [ ty:: GenericArg :: from ( main_ret_ty) ] ) ,
415450 )
@@ -427,7 +462,7 @@ pub fn create_ecx<'tcx>(
427462 ExternAbi :: Rust ,
428463 & [
429464 ImmTy :: from_scalar (
430- Scalar :: from_pointer ( main_ptr, & ecx) ,
465+ Scalar :: from_pointer ( main_ptr, ecx) ,
431466 // FIXME use a proper fn ptr type
432467 ecx. machine . layouts . const_raw_ptr ,
433468 ) ,
@@ -450,7 +485,7 @@ pub fn create_ecx<'tcx>(
450485 }
451486 }
452487
453- interp_ok ( ecx )
488+ interp_ok ( ( ) )
454489}
455490
456491/// Evaluates the entry function specified by `entry_id`.
0 commit comments