@@ -80,82 +80,62 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
8080 ) ) ;
8181 }
8282
83- let libstd_has_mir = {
84- let rustc_panic = ecx. resolve_path ( & [ "std" , "panicking" , "rust_panic" ] ) ?;
85- ecx. load_mir ( rustc_panic. def ) . is_ok ( )
86- } ;
87-
88- if libstd_has_mir {
89- let start_id = tcx. lang_items ( ) . start_fn ( ) . unwrap ( ) ;
90- let main_ret_ty = tcx. fn_sig ( main_id) . output ( ) ;
91- let main_ret_ty = main_ret_ty. no_bound_vars ( ) . unwrap ( ) ;
92- let start_instance = ty:: Instance :: resolve (
93- ecx. tcx . tcx ,
94- ty:: ParamEnv :: reveal_all ( ) ,
95- start_id,
96- ecx. tcx . mk_substs (
97- :: std:: iter:: once ( ty:: subst:: Kind :: from ( main_ret_ty) ) )
98- ) . unwrap ( ) ;
99- let start_mir = ecx. load_mir ( start_instance. def ) ?;
100-
101- if start_mir. arg_count != 3 {
102- return err ! ( AbiViolation ( format!(
103- "'start' lang item should have three arguments, but has {}" ,
104- start_mir. arg_count
105- ) ) ) ;
106- }
107-
108- // Return value (in static memory so that it does not count as leak)
109- let ret = ecx. layout_of ( start_mir. return_ty ( ) ) ?;
110- let ret_ptr = ecx. allocate ( ret, MiriMemoryKind :: MutStatic . into ( ) ) ?;
111-
112- // Push our stack frame
113- ecx. push_stack_frame (
114- start_instance,
115- DUMMY_SP , // there is no call site, we want no span
116- start_mir,
117- Some ( ret_ptr. into ( ) ) ,
118- StackPopCleanup :: None { cleanup : true } ,
119- ) ?;
120-
121- let mut args = ecx. frame ( ) . mir . args_iter ( ) ;
122-
123- // First argument: pointer to main()
124- let main_ptr = ecx. memory_mut ( ) . create_fn_alloc ( main_instance) . with_default_tag ( ) ;
125- let dest = ecx. eval_place ( & mir:: Place :: Local ( args. next ( ) . unwrap ( ) ) ) ?;
126- ecx. write_scalar ( Scalar :: Ptr ( main_ptr) , dest) ?;
127-
128- // Second argument (argc): 1
129- let dest = ecx. eval_place ( & mir:: Place :: Local ( args. next ( ) . unwrap ( ) ) ) ?;
130- ecx. write_scalar ( Scalar :: from_int ( 1 , dest. layout . size ) , dest) ?;
131-
132- // FIXME: extract main source file path
133- // Third argument (argv): &[b"foo"]
134- let dest = ecx. eval_place ( & mir:: Place :: Local ( args. next ( ) . unwrap ( ) ) ) ?;
135- let foo = ecx. memory_mut ( ) . allocate_static_bytes ( b"foo\0 " ) . with_default_tag ( ) ;
136- let foo_ty = ecx. tcx . mk_imm_ptr ( ecx. tcx . types . u8 ) ;
137- let foo_layout = ecx. layout_of ( foo_ty) ?;
138- let foo_place = ecx. allocate ( foo_layout, MiriMemoryKind :: Env . into ( ) ) ?;
139- ecx. write_scalar ( Scalar :: Ptr ( foo) , foo_place. into ( ) ) ?;
140- ecx. memory_mut ( ) . mark_immutable ( foo_place. to_ptr ( ) ?. alloc_id ) ?;
141- ecx. write_scalar ( foo_place. ptr , dest) ?;
142-
143- assert ! ( args. next( ) . is_none( ) , "start lang item has more arguments than expected" ) ;
144- } else {
145- let ret_place = MPlaceTy :: dangling ( ecx. layout_of ( tcx. mk_unit ( ) ) ?, & ecx) . into ( ) ;
146- ecx. push_stack_frame (
147- main_instance,
148- DUMMY_SP , // there is no call site, we want no span
149- main_mir,
150- Some ( ret_place) ,
151- StackPopCleanup :: None { cleanup : true } ,
152- ) ?;
153-
154- // No arguments
155- let mut args = ecx. frame ( ) . mir . args_iter ( ) ;
156- assert ! ( args. next( ) . is_none( ) , "main function must not have arguments" ) ;
83+ let start_id = tcx. lang_items ( ) . start_fn ( ) . unwrap ( ) ;
84+ let main_ret_ty = tcx. fn_sig ( main_id) . output ( ) ;
85+ let main_ret_ty = main_ret_ty. no_bound_vars ( ) . unwrap ( ) ;
86+ let start_instance = ty:: Instance :: resolve (
87+ ecx. tcx . tcx ,
88+ ty:: ParamEnv :: reveal_all ( ) ,
89+ start_id,
90+ ecx. tcx . mk_substs (
91+ :: std:: iter:: once ( ty:: subst:: Kind :: from ( main_ret_ty) ) )
92+ ) . unwrap ( ) ;
93+ let start_mir = ecx. load_mir ( start_instance. def ) ?;
94+
95+ if start_mir. arg_count != 3 {
96+ return err ! ( AbiViolation ( format!(
97+ "'start' lang item should have three arguments, but has {}" ,
98+ start_mir. arg_count
99+ ) ) ) ;
157100 }
158101
102+ // Return value (in static memory so that it does not count as leak)
103+ let ret = ecx. layout_of ( start_mir. return_ty ( ) ) ?;
104+ let ret_ptr = ecx. allocate ( ret, MiriMemoryKind :: MutStatic . into ( ) ) ?;
105+
106+ // Push our stack frame
107+ ecx. push_stack_frame (
108+ start_instance,
109+ DUMMY_SP , // there is no call site, we want no span
110+ start_mir,
111+ Some ( ret_ptr. into ( ) ) ,
112+ StackPopCleanup :: None { cleanup : true } ,
113+ ) ?;
114+
115+ let mut args = ecx. frame ( ) . mir . args_iter ( ) ;
116+
117+ // First argument: pointer to main()
118+ let main_ptr = ecx. memory_mut ( ) . create_fn_alloc ( main_instance) . with_default_tag ( ) ;
119+ let dest = ecx. eval_place ( & mir:: Place :: Local ( args. next ( ) . unwrap ( ) ) ) ?;
120+ ecx. write_scalar ( Scalar :: Ptr ( main_ptr) , dest) ?;
121+
122+ // Second argument (argc): 1
123+ let dest = ecx. eval_place ( & mir:: Place :: Local ( args. next ( ) . unwrap ( ) ) ) ?;
124+ ecx. write_scalar ( Scalar :: from_int ( 1 , dest. layout . size ) , dest) ?;
125+
126+ // FIXME: extract main source file path
127+ // Third argument (argv): &[b"foo"]
128+ let dest = ecx. eval_place ( & mir:: Place :: Local ( args. next ( ) . unwrap ( ) ) ) ?;
129+ let foo = ecx. memory_mut ( ) . allocate_static_bytes ( b"foo\0 " ) . with_default_tag ( ) ;
130+ let foo_ty = ecx. tcx . mk_imm_ptr ( ecx. tcx . types . u8 ) ;
131+ let foo_layout = ecx. layout_of ( foo_ty) ?;
132+ let foo_place = ecx. allocate ( foo_layout, MiriMemoryKind :: Env . into ( ) ) ?;
133+ ecx. write_scalar ( Scalar :: Ptr ( foo) , foo_place. into ( ) ) ?;
134+ ecx. memory_mut ( ) . mark_immutable ( foo_place. to_ptr ( ) ?. alloc_id ) ?;
135+ ecx. write_scalar ( foo_place. ptr , dest) ?;
136+
137+ assert ! ( args. next( ) . is_none( ) , "start lang item has more arguments than expected" ) ;
138+
159139 Ok ( ecx)
160140}
161141
0 commit comments