@@ -30,6 +30,8 @@ JL_DLLEXPORT _Atomic(int) jl_lineno = 0; // need to update jl_fprint_critical_er
3030// current file name
3131JL_DLLEXPORT _Atomic(const char * ) jl_filename = "none" ; // need to update jl_fprint_critical_error if this is TLS
3232
33+ static jl_value_t * jl_eval_toplevel_stmts (jl_module_t * JL_NONNULL m , jl_array_t * stmts , int fast , int need_value , const char * * toplevel_filename , int * toplevel_lineno );
34+
3335htable_t jl_current_modules ;
3436jl_mutex_t jl_modules_mutex ;
3537
@@ -109,25 +111,10 @@ static int jl_is__toplevel__mod(jl_module_t *mod, jl_task_t *ct)
109111 (jl_value_t * )mod == jl_get_global_value (jl_base_module , jl_symbol ("__toplevel__" ), ct -> world_age );
110112}
111113
112- // TODO: add locks around global state mutation operations
113- static jl_value_t * jl_eval_module_expr ( jl_module_t * parent_module , jl_expr_t * ex )
114+ JL_DLLEXPORT jl_module_t * jl_begin_new_module ( jl_module_t * parent_module , jl_sym_t * name ,
115+ int std_imports , const char * filename , int lineno )
114116{
115117 jl_task_t * ct = jl_current_task ;
116- assert (ex -> head == jl_module_sym );
117- if (jl_array_nrows (ex -> args ) != 3 || !jl_is_expr (jl_exprarg (ex , 2 ))) {
118- jl_error ("syntax: malformed module expression" );
119- }
120-
121- if (((jl_expr_t * )(jl_exprarg (ex , 2 )))-> head != jl_symbol ("block" )) {
122- jl_error ("syntax: module expression third argument must be a block" );
123- }
124-
125- int std_imports = (jl_exprarg (ex , 0 ) == jl_true );
126- jl_sym_t * name = (jl_sym_t * )jl_exprarg (ex , 1 );
127- if (!jl_is_symbol (name )) {
128- jl_type_error ("module" , (jl_value_t * )jl_symbol_type , (jl_value_t * )name );
129- }
130-
131118 int is_parent__toplevel__ = jl_is__toplevel__mod (parent_module , ct );
132119 // If we have `Base`, don't also try to import `Core` - the `Base` exports are a superset.
133120 // While we allow multiple imports of the same binding from different modules, various error printing
@@ -140,18 +127,6 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex
140127 JL_UNLOCK (& jl_modules_mutex );
141128 // copy parent environment info into submodule
142129 newm -> uuid = parent_module -> uuid ;
143- jl_array_t * exprs = ((jl_expr_t * )jl_exprarg (ex , 2 ))-> args ;
144- int lineno = 0 ;
145- const char * filename = "none" ;
146- if (jl_array_nrows (exprs ) > 0 ) {
147- jl_value_t * lineex = jl_array_ptr_ref (exprs , 0 );
148- if (jl_is_linenode (lineex )) {
149- lineno = jl_linenode_line (lineex );
150- jl_value_t * file = jl_linenode_file (lineex );
151- if (jl_is_symbol (file ))
152- filename = jl_symbol_name ((jl_sym_t * )file );
153- }
154- }
155130 newm -> file = jl_symbol (filename );
156131 jl_gc_wb_knownold (newm , newm -> file );
157132 newm -> line = lineno ;
@@ -171,8 +146,6 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex
171146 }
172147 }
173148
174- size_t last_age = ct -> world_age ;
175-
176149 if (parent_module == jl_main_module && name == jl_symbol ("Base" ) && jl_base_module == NULL ) {
177150 // pick up Base module during bootstrap
178151 jl_base_module = newm ;
@@ -187,15 +160,14 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex
187160 else {
188161 jl_declare_constant_val (NULL , parent_module , name , (jl_value_t * )newm );
189162 }
163+ JL_GC_POP ();
190164
191- for (int i = 0 ; i < jl_array_nrows (exprs ); i ++ ) {
192- // process toplevel form
193- form = jl_svecref (jl_lower (jl_array_ptr_ref (exprs , i ), newm , filename , lineno , ~(size_t )0 , 0 ), 0 );
194- ct -> world_age = jl_atomic_load_acquire (& jl_world_counter );
195- (void )jl_toplevel_eval_flex (newm , form , 1 , 1 , & filename , & lineno );
196- }
197- ct -> world_age = last_age ;
165+ return newm ;
166+ }
198167
168+ JL_DLLEXPORT void jl_end_new_module (jl_module_t * newm ) {
169+ jl_value_t * form = NULL ;
170+ JL_GC_PUSH1 (& form );
199171 JL_LOCK (& jl_modules_mutex );
200172 uintptr_t * refcnt = (uintptr_t * )ptrhash_bp (& jl_current_modules , (void * )newm );
201173 assert (* refcnt > (uintptr_t )HT_NOTFOUND );
@@ -206,10 +178,9 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex
206178 jl_module_init_order = jl_alloc_vec_any (0 );
207179 jl_array_ptr_1d_push (jl_module_init_order , (jl_value_t * )newm );
208180
209- // defer init of children until parent is done being defined
210- // then initialize all in definition-finished order
211- // at build time, don't run them at all (defer for runtime)
212- form = NULL ;
181+ // Defer init of direct children until parent is done being defined then
182+ // initialize all in definition-finished order.
183+ // At build time, don't run them at all - defer for runtime
213184 if (!jl_generating_output ()) {
214185 if (!ptrhash_has (& jl_current_modules , (void * )newm -> parent )) {
215186 size_t i , l = jl_array_nrows (jl_module_init_order );
@@ -240,6 +211,43 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex
240211 }
241212
242213 JL_GC_POP ();
214+ }
215+
216+ static jl_value_t * jl_eval_module_expr (jl_module_t * parent_module , jl_expr_t * ex , const char * * toplevel_filename , int * toplevel_lineno )
217+ {
218+ assert (ex -> head == jl_module_sym );
219+ if (jl_array_nrows (ex -> args ) != 3 || !jl_is_expr (jl_exprarg (ex , 2 ))) {
220+ jl_error ("syntax: malformed module expression" );
221+ }
222+
223+ if (((jl_expr_t * )(jl_exprarg (ex , 2 )))-> head != jl_symbol ("block" )) {
224+ jl_error ("syntax: module expression third argument must be a block" );
225+ }
226+ jl_array_t * stmts = ((jl_expr_t * )jl_exprarg (ex , 2 ))-> args ;
227+
228+ int std_imports = (jl_exprarg (ex , 0 ) == jl_true );
229+ jl_sym_t * name = (jl_sym_t * )jl_exprarg (ex , 1 );
230+ if (!jl_is_symbol (name )) {
231+ jl_type_error ("module" , (jl_value_t * )jl_symbol_type , (jl_value_t * )name );
232+ }
233+
234+ int lineno = 0 ;
235+ const char * filename = "none" ;
236+ if (jl_array_nrows (stmts ) > 0 ) {
237+ jl_value_t * lineex = jl_array_ptr_ref (stmts , 0 );
238+ if (jl_is_linenode (lineex )) {
239+ lineno = jl_linenode_line (lineex );
240+ jl_value_t * file = jl_linenode_file (lineex );
241+ if (jl_is_symbol (file ))
242+ filename = jl_symbol_name ((jl_sym_t * )file );
243+ }
244+ }
245+
246+ jl_module_t * newm = jl_begin_new_module (parent_module , name , std_imports , filename , lineno );
247+ JL_GC_PROMISE_ROOTED (newm ); // Rooted in jl_current_modules
248+ jl_eval_toplevel_stmts (newm , stmts , 1 , 0 , toplevel_filename , toplevel_lineno );
249+ jl_end_new_module (newm );
250+
243251 return (jl_value_t * )newm ;
244252}
245253
@@ -596,6 +604,28 @@ JL_DLLEXPORT void jl_eval_const_decl(jl_module_t *m, jl_value_t *arg, jl_value_t
596604 jl_declare_constant_val (b , gm , gs , val );
597605}
598606
607+ static jl_value_t * jl_eval_toplevel_stmts (jl_module_t * JL_NONNULL m , jl_array_t * stmts , int fast , int need_value , const char * * toplevel_filename , int * toplevel_lineno )
608+ {
609+ jl_task_t * ct = jl_current_task ;
610+ size_t last_age = ct -> world_age ;
611+ jl_value_t * root = NULL ;
612+ JL_GC_PUSH1 (& root );
613+ jl_value_t * res = jl_nothing ;
614+ int i ;
615+ for (i = 0 ; i < jl_array_nrows (stmts ); i ++ ) {
616+ root = jl_array_ptr_ref (stmts , i );
617+ if (jl_needs_lowering (root )) {
618+ root = jl_svecref (jl_lower (root , m , * toplevel_filename , * toplevel_lineno , ~(size_t )0 ,
619+ need_value ), 0 );
620+ }
621+ ct -> world_age = jl_atomic_load_acquire (& jl_world_counter );
622+ res = jl_toplevel_eval_flex (m , root , fast , 1 , toplevel_filename , toplevel_lineno );
623+ }
624+ ct -> world_age = last_age ;
625+ JL_GC_POP ();
626+ return res ;
627+ }
628+
599629JL_DLLEXPORT jl_value_t * jl_toplevel_eval_flex (jl_module_t * JL_NONNULL m , jl_value_t * e , int fast , int expanded , const char * * toplevel_filename , int * toplevel_lineno )
600630{
601631 jl_task_t * ct = jl_current_task ;
@@ -654,7 +684,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val
654684 jl_sym_t * head = jl_is_expr (ex ) ? ex -> head : NULL ;
655685
656686 if (head == jl_module_sym ) {
657- jl_value_t * val = jl_eval_module_expr (m , ex );
687+ jl_value_t * val = jl_eval_module_expr (m , ex , toplevel_filename , toplevel_lineno );
658688 JL_GC_POP ();
659689 return val ;
660690 }
@@ -701,17 +731,8 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val
701731 return jl_nothing ;
702732 }
703733 else if (head == jl_toplevel_sym ) {
704- jl_value_t * res = jl_nothing ;
705- int i ;
706- for (i = 0 ; i < jl_array_nrows (ex -> args ); i ++ ) {
707- root = jl_array_ptr_ref (ex -> args , i );
708- if (jl_needs_lowering (root )) {
709- root = jl_svecref (jl_lower (root , m , * toplevel_filename , * toplevel_lineno , ~(size_t )0 , 1 ), 0 );
710- }
711- ct -> world_age = jl_atomic_load_acquire (& jl_world_counter );
712- res = jl_toplevel_eval_flex (m , root , fast , 1 , toplevel_filename , toplevel_lineno );
713- }
714- ct -> world_age = last_age ;
734+ jl_value_t * res = jl_eval_toplevel_stmts (m , ex -> args , fast , 1 ,
735+ toplevel_filename , toplevel_lineno );
715736 JL_GC_POP ();
716737 return res ;
717738 }
0 commit comments