Branch data Line data Source code
1 : : // This file is a part of Julia. License is MIT: https://julialang.org/license
2 : :
3 : : /*
4 : : evaluating top-level expressions, loading source files
5 : : */
6 : : #include "platform.h"
7 : :
8 : : #include <stdlib.h>
9 : : #include <string.h>
10 : : #include <setjmp.h>
11 : : #include <sys/types.h>
12 : : #include <errno.h>
13 : : #if defined(_OS_WINDOWS_)
14 : : #include <malloc.h>
15 : : #else
16 : : #include <unistd.h>
17 : : #endif
18 : : #include "julia.h"
19 : : #include "julia_internal.h"
20 : : #include "julia_assert.h"
21 : : #include "intrinsics.h"
22 : : #include "builtin_proto.h"
23 : :
24 : : #ifdef __cplusplus
25 : : extern "C" {
26 : : #endif
27 : :
28 : : // current line number in a file
29 : : JL_DLLEXPORT int jl_lineno = 0; // need to update jl_critical_error if this is TLS
30 : : // current file name
31 : : JL_DLLEXPORT const char *jl_filename = "none"; // need to update jl_critical_error if this is TLS
32 : :
33 : : htable_t jl_current_modules;
34 : : jl_mutex_t jl_modules_mutex;
35 : :
36 : : // During incremental compilation, the following gets set
37 : : JL_DLLEXPORT jl_module_t *jl_precompile_toplevel_module = NULL; // the toplevel module currently being defined
38 : :
39 : 220 : JL_DLLEXPORT void jl_add_standard_imports(jl_module_t *m)
40 : : {
41 : 220 : jl_module_t *base_module = jl_base_relative_to(m);
42 [ - + ]: 220 : assert(base_module != NULL);
43 : : // using Base
44 : 220 : jl_module_using(m, base_module);
45 : 220 : }
46 : :
47 : : // create a new top-level module
48 : 1 : void jl_init_main_module(void)
49 : : {
50 [ - + ]: 1 : assert(jl_main_module == NULL);
51 : 1 : jl_main_module = jl_new_module(jl_symbol("Main"));
52 : 1 : jl_main_module->parent = jl_main_module;
53 : 1 : jl_set_const(jl_main_module, jl_symbol("Core"),
54 : : (jl_value_t*)jl_core_module);
55 : 1 : jl_set_const(jl_core_module, jl_symbol("Main"),
56 : : (jl_value_t*)jl_main_module);
57 : 1 : }
58 : :
59 : 240 : static jl_function_t *jl_module_get_initializer(jl_module_t *m JL_PROPAGATES_ROOT)
60 : : {
61 : 240 : return (jl_function_t*)jl_get_global(m, jl_symbol("__init__"));
62 : : }
63 : :
64 : :
65 : 240 : void jl_module_run_initializer(jl_module_t *m)
66 : : {
67 : : JL_TIMING(INIT_MODULE);
68 : 240 : jl_function_t *f = jl_module_get_initializer(m);
69 [ - + ]: 240 : if (f == NULL)
70 : 0 : return;
71 : 240 : jl_task_t *ct = jl_current_task;
72 : 240 : size_t last_age = ct->world_age;
73 [ + - + + ]: 480 : JL_TRY {
74 : 240 : ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
75 : 240 : jl_apply(&f, 1);
76 : 240 : ct->world_age = last_age;
77 : : }
78 [ # # ]: 0 : JL_CATCH {
79 [ # # ]: 0 : if (jl_initerror_type == NULL) {
80 : 0 : jl_rethrow();
81 : : }
82 : : else {
83 : 0 : jl_rethrow_other(jl_new_struct(jl_initerror_type, m->name,
84 : : jl_current_exception()));
85 : : }
86 : : }
87 : : }
88 : :
89 : 84 : static void jl_register_root_module(jl_module_t *m)
90 : : {
91 : : static jl_value_t *register_module_func = NULL;
92 [ - + ]: 84 : assert(jl_base_module);
93 [ + + ]: 84 : if (register_module_func == NULL)
94 : 6 : register_module_func = jl_get_global(jl_base_module, jl_symbol("register_root_module"));
95 [ - + ]: 84 : assert(register_module_func);
96 : : jl_value_t *args[2];
97 : 84 : args[0] = register_module_func;
98 : 84 : args[1] = (jl_value_t*)m;
99 : 84 : jl_apply(args, 2);
100 : 84 : }
101 : :
102 : 15 : jl_array_t *jl_get_loaded_modules(void)
103 : : {
104 : : static jl_value_t *loaded_modules_array = NULL;
105 [ + + + + ]: 15 : if (loaded_modules_array == NULL && jl_base_module != NULL)
106 : 8 : loaded_modules_array = jl_get_global(jl_base_module, jl_symbol("loaded_modules_array"));
107 [ + + ]: 15 : if (loaded_modules_array != NULL)
108 : 12 : return (jl_array_t*)jl_call0((jl_function_t*)loaded_modules_array);
109 : 3 : return NULL;
110 : : }
111 : :
112 : 249 : static int jl_is__toplevel__mod(jl_module_t *mod)
113 : : {
114 [ + + + + ]: 487 : return jl_base_module &&
115 : 238 : (jl_value_t*)mod == jl_get_global(jl_base_module, jl_symbol("__toplevel__"));
116 : : }
117 : :
118 : : // TODO: add locks around global state mutation operations
119 : 245 : static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex)
120 : : {
121 : 245 : jl_task_t *ct = jl_current_task;
122 [ - + ]: 245 : assert(ex->head == jl_module_sym);
123 [ + - - + ]: 245 : if (jl_array_len(ex->args) != 3 || !jl_is_expr(jl_exprarg(ex, 2))) {
124 : 0 : jl_error("syntax: malformed module expression");
125 : : }
126 : :
127 [ - + ]: 245 : if (((jl_expr_t *)(jl_exprarg(ex, 2)))->head != jl_symbol("block")) {
128 : 0 : jl_error("syntax: module expression third argument must be a block");
129 : : }
130 : :
131 : 245 : int std_imports = (jl_exprarg(ex, 0) == jl_true);
132 : 245 : jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1);
133 [ - + ]: 245 : if (!jl_is_symbol(name)) {
134 : 0 : jl_type_error("module", (jl_value_t*)jl_symbol_type, (jl_value_t*)name);
135 : : }
136 : :
137 : 245 : jl_module_t *newm = jl_new_module(name);
138 : 245 : jl_value_t *form = (jl_value_t*)newm;
139 : 245 : JL_GC_PUSH1(&form);
140 : 245 : JL_LOCK(&jl_modules_mutex);
141 : 245 : ptrhash_put(&jl_current_modules, (void*)newm, (void*)((uintptr_t)HT_NOTFOUND + 1));
142 : 245 : JL_UNLOCK(&jl_modules_mutex);
143 : :
144 : 245 : jl_module_t *old_toplevel_module = jl_precompile_toplevel_module;
145 : :
146 : : // copy parent environment info into submodule
147 : 245 : newm->uuid = parent_module->uuid;
148 [ + + ]: 245 : if (jl_is__toplevel__mod(parent_module)) {
149 : 84 : newm->parent = newm;
150 : 84 : jl_register_root_module(newm);
151 [ + + ]: 84 : if (jl_options.incremental) {
152 : 4 : jl_precompile_toplevel_module = newm;
153 : : }
154 : : }
155 : : else {
156 : 161 : newm->parent = parent_module;
157 : 161 : jl_binding_t *b = jl_get_binding_wr(parent_module, name, 1);
158 : 161 : jl_declare_constant(b);
159 : 161 : jl_value_t *old = NULL;
160 [ - + ]: 161 : if (!jl_atomic_cmpswap(&b->value, &old, (jl_value_t*)newm)) {
161 [ # # ]: 0 : if (!jl_is_module(old)) {
162 : 0 : jl_errorf("invalid redefinition of constant %s", jl_symbol_name(name));
163 : : }
164 [ # # ]: 0 : if (jl_generating_output())
165 : 0 : jl_errorf("cannot replace module %s during compilation", jl_symbol_name(name));
166 : 0 : jl_printf(JL_STDERR, "WARNING: replacing module %s.\n", jl_symbol_name(name));
167 : 0 : old = jl_atomic_exchange(&b->value, (jl_value_t*)newm);
168 : : }
169 : 161 : jl_gc_wb_binding(b, newm);
170 [ - + ]: 161 : if (old != NULL) {
171 : : // create a hidden gc root for the old module
172 : 0 : JL_LOCK(&jl_modules_mutex);
173 : 0 : uintptr_t *refcnt = (uintptr_t*)ptrhash_bp(&jl_current_modules, (void*)old);
174 : 0 : *refcnt += 1;
175 : 0 : JL_UNLOCK(&jl_modules_mutex);
176 : : }
177 : : }
178 : :
179 [ + + + - ]: 245 : if (parent_module == jl_main_module && name == jl_symbol("Base")) {
180 : : // pick up Base module during bootstrap
181 : 2 : jl_base_module = newm;
182 : : }
183 : :
184 : 245 : size_t last_age = ct->world_age;
185 : :
186 : : // add standard imports unless baremodule
187 [ + + ]: 245 : if (std_imports) {
188 [ + + ]: 220 : if (jl_base_module != NULL) {
189 : 214 : jl_add_standard_imports(newm);
190 : : }
191 : : // add `eval` function
192 : 220 : form = jl_call_scm_on_ast("module-default-defs", (jl_value_t*)ex, newm);
193 : 220 : jl_toplevel_eval_flex(newm, form, 0, 1);
194 : 220 : form = NULL;
195 : : }
196 : :
197 : 245 : jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 2))->args;
198 [ + + ]: 27756 : for (int i = 0; i < jl_array_len(exprs); i++) {
199 : : // process toplevel form
200 : 27511 : ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
201 : 27511 : form = jl_expand_stmt_with_loc(jl_array_ptr_ref(exprs, i), newm, jl_filename, jl_lineno);
202 : 27511 : ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
203 : 27511 : (void)jl_toplevel_eval_flex(newm, form, 1, 1);
204 : : }
205 : 245 : newm->primary_world = jl_atomic_load_acquire(&jl_world_counter);
206 : 245 : ct->world_age = last_age;
207 : :
208 : : #if 0
209 : : // some optional post-processing steps
210 : : size_t i;
211 : : void **table = newm->bindings.table;
212 : : for(i=1; i < newm->bindings.size; i+=2) {
213 : : if (table[i] != HT_NOTFOUND) {
214 : : jl_binding_t *b = (jl_binding_t*)table[i];
215 : : // remove non-exported macros
216 : : if (jl_symbol_name(b->name)[0]=='@' &&
217 : : !b->exportp && b->owner == newm)
218 : : b->value = NULL;
219 : : // error for unassigned exports
220 : : /*
221 : : if (b->exportp && b->owner==newm && b->value==NULL)
222 : : jl_errorf("identifier %s exported from %s is not initialized",
223 : : jl_symbol_name(b->name), jl_symbol_name(newm->name));
224 : : */
225 : : }
226 : : }
227 : : #endif
228 : :
229 : 245 : JL_LOCK(&jl_modules_mutex);
230 : 245 : uintptr_t *refcnt = (uintptr_t*)ptrhash_bp(&jl_current_modules, (void*)newm);
231 [ - + ]: 245 : assert(*refcnt > (uintptr_t)HT_NOTFOUND);
232 : 245 : *refcnt -= 1;
233 : : // newm should be reachable from somewhere else by now
234 : :
235 [ + + ]: 245 : if (jl_module_init_order == NULL)
236 : 5 : jl_module_init_order = jl_alloc_vec_any(0);
237 : 245 : jl_array_ptr_1d_push(jl_module_init_order, (jl_value_t*)newm);
238 : :
239 : : // defer init of children until parent is done being defined
240 : : // then initialize all in definition-finished order
241 : : // at build time, don't run them at all (defer for runtime)
242 : 245 : form = NULL;
243 [ - + ]: 245 : if (!jl_generating_output()) {
244 [ # # ]: 0 : if (!ptrhash_has(&jl_current_modules, (void*)newm->parent)) {
245 : 0 : size_t i, l = jl_array_len(jl_module_init_order);
246 : 0 : size_t ns = 0;
247 : 0 : form = (jl_value_t*)jl_alloc_vec_any(0);
248 [ # # ]: 0 : for (i = 0; i < l; i++) {
249 : 0 : jl_module_t *m = (jl_module_t*)jl_array_ptr_ref(jl_module_init_order, i);
250 [ # # ]: 0 : if (jl_is_submodule(m, newm)) {
251 : 0 : jl_array_ptr_1d_push((jl_array_t*)form, (jl_value_t*)m);
252 : : }
253 [ # # ]: 0 : else if (ns++ != i) {
254 : 0 : jl_array_ptr_set(jl_module_init_order, ns - 1, (jl_value_t*)m);
255 : : }
256 : : }
257 [ # # ]: 0 : if (ns < l)
258 : 0 : jl_array_del_end(jl_module_init_order, l - ns);
259 : : }
260 : : }
261 : 245 : JL_UNLOCK(&jl_modules_mutex);
262 : :
263 [ - + ]: 245 : if (form) {
264 : 0 : size_t i, l = jl_array_len(form);
265 [ # # ]: 0 : for (i = 0; i < l; i++) {
266 : 0 : jl_module_t *m = (jl_module_t*)jl_array_ptr_ref(form, i);
267 : : JL_GC_PROMISE_ROOTED(m);
268 : 0 : jl_module_run_initializer(m);
269 : : }
270 : : }
271 : :
272 : 245 : jl_precompile_toplevel_module = old_toplevel_module;
273 : :
274 : 245 : JL_GC_POP();
275 : 245 : return (jl_value_t*)newm;
276 : : }
277 : :
278 : 1050 : static jl_value_t *jl_eval_dot_expr(jl_module_t *m, jl_value_t *x, jl_value_t *f, int fast)
279 : : {
280 : 1050 : jl_task_t *ct = jl_current_task;
281 : : jl_value_t **args;
282 : 1050 : JL_GC_PUSHARGS(args, 3);
283 : 1050 : args[1] = jl_toplevel_eval_flex(m, x, fast, 0);
284 : 1050 : args[2] = jl_toplevel_eval_flex(m, f, fast, 0);
285 [ + - ]: 1050 : if (jl_is_module(args[1])) {
286 [ - + ]: 1050 : JL_TYPECHK(getglobal, symbol, args[2]);
287 : 1050 : args[0] = jl_eval_global_var((jl_module_t*)args[1], (jl_sym_t*)args[2]);
288 : : }
289 : : else {
290 : 0 : args[0] = jl_eval_global_var(jl_base_relative_to(m), jl_symbol("getproperty"));
291 : 0 : size_t last_age = ct->world_age;
292 : 0 : ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
293 : 0 : args[0] = jl_apply(args, 3);
294 : 0 : ct->world_age = last_age;
295 : : }
296 : 1050 : JL_GC_POP();
297 : 1050 : return args[0];
298 : : }
299 : :
300 : 7739 : void jl_eval_global_expr(jl_module_t *m, jl_expr_t *ex, int set_type) {
301 : : // create uninitialized mutable binding for "global x" decl sometimes or probably
302 : 7739 : size_t i, l = jl_array_len(ex->args);
303 [ + + ]: 15478 : for (i = 0; i < l; i++) {
304 : 7739 : jl_value_t *arg = jl_exprarg(ex, i);
305 : : jl_module_t *gm;
306 : : jl_sym_t *gs;
307 [ - + ]: 7739 : if (jl_is_globalref(arg)) {
308 : 0 : gm = jl_globalref_mod(arg);
309 : 0 : gs = jl_globalref_name(arg);
310 : : }
311 : : else {
312 [ - + ]: 7739 : assert(jl_is_symbol(arg));
313 : 7739 : gm = m;
314 : 7739 : gs = (jl_sym_t*)arg;
315 : : }
316 [ + + ]: 7739 : if (!jl_binding_resolved_p(gm, gs)) {
317 : 5724 : jl_binding_t *b = jl_get_binding_wr(gm, gs, 1);
318 [ + + ]: 5724 : if (set_type) {
319 : 20 : jl_value_t *old_ty = NULL;
320 : : // maybe set the type too, perhaps
321 : 20 : jl_atomic_cmpswap_relaxed(&b->ty, &old_ty, (jl_value_t*)jl_any_type);
322 : : }
323 : : }
324 : : }
325 : 7739 : }
326 : :
327 : : // module referenced by (top ...) from within m
328 : : // this is only needed because of the bootstrapping process:
329 : : // - initially Base doesn't exist and top === Core
330 : : // - later, it refers to either old Base or new Base
331 : 1124560 : JL_DLLEXPORT jl_module_t *jl_base_relative_to(jl_module_t *m)
332 : : {
333 : : for (;;) {
334 [ + + ]: 1124560 : if (m->istopmod)
335 : 848084 : return m;
336 [ + + ]: 276477 : if (m == m->parent)
337 : 148473 : break;
338 : 128004 : m = m->parent;
339 : : }
340 : 148473 : return jl_top_module;
341 : : }
342 : :
343 : 834053 : static void expr_attributes(jl_value_t *v, int *has_intrinsics, int *has_defs, int *has_opaque)
344 : : {
345 [ + + ]: 834053 : if (!jl_is_expr(v))
346 : 139820 : return;
347 : 694233 : jl_expr_t *e = (jl_expr_t*)v;
348 : 694233 : jl_sym_t *head = e->head;
349 [ + + + + ]: 694233 : if (head == jl_toplevel_sym || head == jl_thunk_sym) {
350 : 44493 : return;
351 : : }
352 [ + + ]: 649740 : else if (head == jl_global_sym) {
353 : : // this could be considered has_defs, but loops that assign to globals
354 : : // might still need to be optimized.
355 : 7561 : return;
356 : : }
357 [ + + + + ]: 642179 : else if (head == jl_const_sym || head == jl_copyast_sym) {
358 : : // Note: `copyast` is included here since it indicates the presence of
359 : : // `quote` and probably `eval`.
360 : 29283 : *has_defs = 1;
361 : 29283 : return;
362 : : }
363 [ + + + + ]: 612896 : else if (head == jl_method_sym || jl_is_toplevel_only_expr(v)) {
364 : 106156 : *has_defs = 1;
365 : : }
366 [ - + ]: 506740 : else if (head == jl_cfunction_sym) {
367 : 0 : *has_intrinsics = 1;
368 : 0 : return;
369 : : }
370 [ + + ]: 506740 : else if (head == jl_foreigncall_sym) {
371 : 56 : *has_intrinsics = 1;
372 : 56 : return;
373 : : }
374 [ - + ]: 506684 : else if (head == jl_new_opaque_closure_sym) {
375 : 0 : *has_opaque = 1;
376 : 0 : return;
377 : : }
378 [ + + + - ]: 506684 : else if (head == jl_call_sym && jl_expr_nargs(e) > 0) {
379 : 471997 : jl_value_t *called = NULL;
380 : 471997 : jl_value_t *f = jl_exprarg(e, 0);
381 [ + + ]: 471997 : if (jl_is_globalref(f)) {
382 : 403759 : jl_module_t *mod = jl_globalref_mod(f);
383 : 403759 : jl_sym_t *name = jl_globalref_name(f);
384 [ + + ]: 403759 : if (jl_binding_resolved_p(mod, name)) {
385 : 403687 : jl_binding_t *b = jl_get_binding(mod, name);
386 [ + - + - ]: 403687 : if (b && b->constp) {
387 : 403687 : called = jl_atomic_load_relaxed(&b->value);
388 : : }
389 : : }
390 : : }
391 [ - + ]: 68238 : else if (jl_is_quotenode(f)) {
392 : 0 : called = jl_quotenode_value(f);
393 : : }
394 [ + + ]: 471997 : if (called != NULL) {
395 [ + + - + ]: 403687 : if (jl_is_intrinsic(called) && jl_unbox_int32(called) == (int)llvmcall) {
396 : 0 : *has_intrinsics = 1;
397 : : }
398 [ + + ]: 403687 : if (called == jl_builtin__typebody) {
399 : 5587 : *has_defs = 1;
400 : : }
401 : : }
402 : 471997 : return;
403 : : }
404 : : int i;
405 [ + + ]: 427391 : for (i = 0; i < jl_array_len(e->args); i++) {
406 : 286548 : jl_value_t *a = jl_exprarg(e, i);
407 [ + + ]: 286548 : if (jl_is_expr(a))
408 : 8113 : expr_attributes(a, has_intrinsics, has_defs, has_opaque);
409 : : }
410 : : }
411 : :
412 : 72 : int jl_code_requires_compiler(jl_code_info_t *src)
413 : : {
414 : 72 : jl_array_t *body = src->code;
415 [ - + ]: 72 : assert(jl_typeis(body, jl_array_any_type));
416 : : size_t i;
417 : 72 : int has_intrinsics = 0, has_defs = 0, has_opaque = 0;
418 [ - + ]: 72 : if (jl_has_meta(body, jl_force_compile_sym))
419 : 0 : return 1;
420 [ + + ]: 2044 : for(i=0; i < jl_array_len(body); i++) {
421 : 1972 : jl_value_t *stmt = jl_array_ptr_ref(body,i);
422 : 1972 : expr_attributes(stmt, &has_intrinsics, &has_defs, &has_opaque);
423 [ - + ]: 1972 : if (has_intrinsics)
424 : 0 : return 1;
425 : : }
426 : 72 : return 0;
427 : : }
428 : :
429 : 104939 : static void body_attributes(jl_array_t *body, int *has_intrinsics, int *has_defs, int *has_loops, int *has_opaque, int *forced_compile)
430 : : {
431 : : size_t i;
432 : 104939 : *has_loops = 0;
433 [ + + ]: 928907 : for(i=0; i < jl_array_len(body); i++) {
434 : 823968 : jl_value_t *stmt = jl_array_ptr_ref(body,i);
435 [ + + ]: 823968 : if (!*has_loops) {
436 [ + + ]: 820671 : if (jl_is_gotonode(stmt)) {
437 [ + + ]: 5037 : if (jl_gotonode_label(stmt) <= i)
438 : 652 : *has_loops = 1;
439 : : }
440 [ + + ]: 815634 : else if (jl_is_gotoifnot(stmt)) {
441 [ - + ]: 8063 : if (jl_gotoifnot_label(stmt) <= i)
442 : 0 : *has_loops = 1;
443 : : }
444 : : }
445 : 823968 : expr_attributes(stmt, has_intrinsics, has_defs, has_opaque);
446 : : }
447 : 104939 : *forced_compile = jl_has_meta(body, jl_force_compile_sym);
448 : 104939 : }
449 : :
450 : 250 : static jl_module_t *call_require(jl_module_t *mod, jl_sym_t *var) JL_GLOBALLY_ROOTED
451 : : {
452 : : static jl_value_t *require_func = NULL;
453 : 250 : int build_mode = jl_generating_output();
454 : 250 : jl_module_t *m = NULL;
455 : 250 : jl_task_t *ct = jl_current_task;
456 [ + + + - ]: 250 : if (require_func == NULL && jl_base_module != NULL) {
457 : 6 : require_func = jl_get_global(jl_base_module, jl_symbol("require"));
458 : : }
459 [ + - ]: 250 : if (require_func != NULL) {
460 : 250 : size_t last_age = ct->world_age;
461 [ + + ]: 250 : ct->world_age = (build_mode ? jl_base_module->primary_world : jl_atomic_load_acquire(&jl_world_counter));
462 : : jl_value_t *reqargs[3];
463 : 250 : reqargs[0] = require_func;
464 : 250 : reqargs[1] = (jl_value_t*)mod;
465 : 250 : reqargs[2] = (jl_value_t*)var;
466 : 250 : m = (jl_module_t*)jl_apply(reqargs, 3);
467 : 250 : ct->world_age = last_age;
468 : : }
469 [ + - - + ]: 250 : if (m == NULL || !jl_is_module(m)) {
470 : 0 : jl_errorf("failed to load module %s", jl_symbol_name(var));
471 : : }
472 : 250 : return m;
473 : : }
474 : :
475 : : // either:
476 : : // - sets *name and returns the module to import *name from
477 : : // - sets *name to NULL and returns a module to import
478 : 4265 : static jl_module_t *eval_import_path(jl_module_t *where, jl_module_t *from JL_PROPAGATES_ROOT,
479 : : jl_array_t *args, jl_sym_t **name, const char *keyword) JL_GLOBALLY_ROOTED
480 : : {
481 [ - + ]: 4265 : if (jl_array_len(args) == 0)
482 : 0 : jl_errorf("malformed \"%s\" statement", keyword);
483 : 4265 : jl_sym_t *var = (jl_sym_t*)jl_array_ptr_ref(args, 0);
484 : 4265 : size_t i = 1;
485 : 4265 : jl_module_t *m = NULL;
486 : 4265 : *name = NULL;
487 [ - + ]: 4265 : if (!jl_is_symbol(var))
488 : 0 : jl_type_error(keyword, (jl_value_t*)jl_symbol_type, (jl_value_t*)var);
489 : :
490 [ + + ]: 4265 : if (from != NULL) {
491 : 3184 : m = from;
492 : 3184 : i = 0;
493 : : }
494 [ + + ]: 1081 : else if (var != jl_dot_sym) {
495 : : // `A.B`: call the loader to obtain the root A in the current environment.
496 [ + - + + ]: 629 : if (jl_core_module && var == jl_core_module->name) {
497 : 59 : m = jl_core_module;
498 : : }
499 [ + - + + ]: 570 : else if (jl_base_module && var == jl_base_module->name) {
500 : 320 : m = jl_base_module;
501 : : }
502 : : else {
503 : 250 : m = call_require(where, var);
504 : : }
505 [ + + ]: 629 : if (i == jl_array_len(args))
506 : 414 : return m;
507 : : }
508 : : else {
509 : : // `.A.B.C`: strip off leading dots by following parent links
510 : 452 : m = where;
511 : : while (1) {
512 [ - + ]: 719 : if (i >= jl_array_len(args))
513 : 0 : jl_error("invalid module path");
514 : 719 : var = (jl_sym_t*)jl_array_ptr_ref(args, i);
515 [ + + ]: 719 : if (var != jl_dot_sym)
516 : 452 : break;
517 : 267 : i++;
518 [ - + ]: 267 : assert(m);
519 : 267 : m = m->parent;
520 : : }
521 : : }
522 : :
523 : : while (1) {
524 : 3901 : var = (jl_sym_t*)jl_array_ptr_ref(args, i);
525 [ - + ]: 3901 : if (!jl_is_symbol(var))
526 : 0 : jl_type_error(keyword, (jl_value_t*)jl_symbol_type, (jl_value_t*)var);
527 [ - + ]: 3901 : if (var == jl_dot_sym)
528 : 0 : jl_errorf("invalid %s path: \".\" in identifier path", keyword);
529 [ + + ]: 3901 : if (i == jl_array_len(args)-1)
530 : 3851 : break;
531 : 50 : m = (jl_module_t*)jl_eval_global_var(m, var);
532 : : JL_GC_PROMISE_ROOTED(m);
533 [ - + ]: 50 : if (!jl_is_module(m))
534 : 0 : jl_errorf("invalid %s path: \"%s\" does not name a module", keyword, jl_symbol_name(var));
535 : 50 : i++;
536 : : }
537 : 3851 : *name = var;
538 : 3851 : return m;
539 : : }
540 : :
541 : 1919270 : int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT
542 : : {
543 [ + + ]: 3838390 : return jl_is_expr(e) &&
544 [ + - ]: 1919120 : (((jl_expr_t*)e)->head == jl_module_sym ||
545 [ + + ]: 1919120 : ((jl_expr_t*)e)->head == jl_import_sym ||
546 [ + + ]: 1919100 : ((jl_expr_t*)e)->head == jl_using_sym ||
547 [ + + ]: 1919080 : ((jl_expr_t*)e)->head == jl_export_sym ||
548 [ + + ]: 1919060 : ((jl_expr_t*)e)->head == jl_thunk_sym ||
549 [ + + ]: 1874810 : ((jl_expr_t*)e)->head == jl_global_sym ||
550 [ + + ]: 1867230 : ((jl_expr_t*)e)->head == jl_const_sym ||
551 [ + - ]: 1853910 : ((jl_expr_t*)e)->head == jl_toplevel_sym ||
552 [ + - ]: 1853910 : ((jl_expr_t*)e)->head == jl_error_sym ||
553 [ - + ]: 1853910 : ((jl_expr_t*)e)->head == jl_incomplete_sym);
554 : : }
555 : :
556 : 111647 : int jl_needs_lowering(jl_value_t *e) JL_NOTSAFEPOINT
557 : : {
558 [ - + ]: 111647 : if (!jl_is_expr(e))
559 : 0 : return 0;
560 : 111647 : jl_expr_t *ex = (jl_expr_t*)e;
561 : 111647 : jl_sym_t *head = ex->head;
562 [ + + + + : 111647 : if (head == jl_module_sym || head == jl_import_sym || head == jl_using_sym ||
+ + ]
563 [ + + + + : 111319 : head == jl_export_sym || head == jl_thunk_sym || head == jl_toplevel_sym ||
+ + ]
564 [ + - + - : 48193 : head == jl_error_sym || head == jl_incomplete_sym || head == jl_method_sym) {
- + ]
565 : 63454 : return 0;
566 : : }
567 [ + + + + ]: 48193 : if (head == jl_global_sym || head == jl_const_sym) {
568 : 24595 : size_t i, l = jl_array_len(ex->args);
569 [ + + ]: 45440 : for (i = 0; i < l; i++) {
570 : 24595 : jl_value_t *a = jl_exprarg(ex, i);
571 [ + + + - ]: 24595 : if (!jl_is_symbol(a) && !jl_is_globalref(a))
572 : 3750 : return 1;
573 : : }
574 : 20845 : return 0;
575 : : }
576 : 23598 : return 1;
577 : : }
578 : :
579 : 99 : static jl_method_instance_t *method_instance_for_thunk(jl_code_info_t *src, jl_module_t *module)
580 : : {
581 : 99 : jl_method_instance_t *li = jl_new_method_instance_uninit();
582 : 99 : li->uninferred = (jl_value_t*)src;
583 : 99 : li->specTypes = (jl_value_t*)jl_emptytuple_type;
584 : 99 : li->def.module = module;
585 : 99 : return li;
586 : : }
587 : :
588 : 60 : static void import_module(jl_module_t *JL_NONNULL m, jl_module_t *import, jl_sym_t *asname)
589 : : {
590 [ - + ]: 60 : assert(m);
591 [ + - ]: 60 : jl_sym_t *name = asname ? asname : import->name;
592 : : jl_binding_t *b;
593 [ + + ]: 60 : if (jl_binding_resolved_p(m, name)) {
594 : 2 : b = jl_get_binding(m, name);
595 : 2 : jl_value_t *bv = jl_atomic_load_relaxed(&b->value);
596 [ - + - - : 2 : if ((!b->constp && b->owner != m) || (bv && bv != (jl_value_t*)import)) {
+ - - + ]
597 : 0 : jl_errorf("importing %s into %s conflicts with an existing global",
598 : : jl_symbol_name(name), jl_symbol_name(m->name));
599 : : }
600 : : }
601 : : else {
602 : 58 : b = jl_get_binding_wr(m, name, 1);
603 : 58 : b->imported = 1;
604 : : }
605 [ + + ]: 60 : if (!b->constp) {
606 : : // TODO: constp is not threadsafe
607 : 58 : jl_atomic_store_release(&b->value, (jl_value_t*)import);
608 : 58 : b->constp = 1;
609 : 58 : jl_gc_wb(m, (jl_value_t*)import);
610 : : }
611 : 60 : }
612 : :
613 : : // in `import A.B: x, y, ...`, evaluate the `A.B` part if it exists
614 : 930 : static jl_module_t *eval_import_from(jl_module_t *m JL_PROPAGATES_ROOT, jl_expr_t *ex, const char *keyword)
615 : : {
616 [ + + + - ]: 930 : if (jl_expr_nargs(ex) == 1 && jl_is_expr(jl_exprarg(ex, 0))) {
617 : 853 : jl_expr_t *fr = (jl_expr_t*)jl_exprarg(ex, 0);
618 [ + + ]: 853 : if (fr->head == jl_colon_sym) {
619 [ + - + - ]: 530 : if (jl_expr_nargs(fr) > 0 && jl_is_expr(jl_exprarg(fr, 0))) {
620 : 530 : jl_expr_t *path = (jl_expr_t*)jl_exprarg(fr, 0);
621 [ + - ]: 530 : if (((jl_expr_t*)path)->head == jl_dot_sym) {
622 : 530 : jl_sym_t *name = NULL;
623 : 530 : jl_module_t *from = eval_import_path(m, NULL, path->args, &name, keyword);
624 [ + + ]: 530 : if (name != NULL) {
625 : 314 : from = (jl_module_t*)jl_eval_global_var(from, name);
626 [ - + ]: 314 : if (!jl_is_module(from))
627 : 0 : jl_errorf("invalid %s path: \"%s\" does not name a module", keyword, jl_symbol_name(name));
628 : : }
629 : 530 : return from;
630 : : }
631 : : }
632 : 0 : jl_errorf("malformed \"%s:\" statement", keyword);
633 : : }
634 : : }
635 : 400 : return NULL;
636 : : }
637 : :
638 : 0 : static void check_macro_rename(jl_sym_t *from, jl_sym_t *to, const char *keyword)
639 : : {
640 : 0 : char *n1 = jl_symbol_name(from), *n2 = jl_symbol_name(to);
641 [ # # # # ]: 0 : if (n1[0] == '@' && n2[0] != '@')
642 : 0 : jl_errorf("cannot rename macro \"%s\" to non-macro \"%s\" in \"%s\"", n1, n2, keyword);
643 [ # # # # ]: 0 : if (n1[0] != '@' && n2[0] == '@')
644 : 0 : jl_errorf("cannot rename non-macro \"%s\" to macro \"%s\" in \"%s\"", n1, n2, keyword);
645 : 0 : }
646 : :
647 : : // Format msg and eval `throw(ErrorException(msg)))` in module `m`.
648 : : // Used in `jl_toplevel_eval_flex` instead of `jl_errorf` so that the error
649 : : // location in julia code gets into the backtrace.
650 : 0 : static void jl_eval_errorf(jl_module_t *m, const char* fmt, ...)
651 : : {
652 : 0 : jl_value_t *throw_ex = (jl_value_t*)jl_exprn(jl_call_sym, 2);
653 : 0 : JL_GC_PUSH1(&throw_ex);
654 : 0 : jl_exprargset(throw_ex, 0, jl_builtin_throw);
655 : : va_list args;
656 : 0 : va_start(args, fmt);
657 : 0 : jl_exprargset(throw_ex, 1, jl_vexceptionf(jl_errorexception_type, fmt, args));
658 : 0 : va_end(args);
659 : 0 : jl_toplevel_eval_flex(m, throw_ex, 0, 0);
660 : 0 : JL_GC_POP();
661 : 0 : }
662 : :
663 : 208454 : jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_value_t *e, int fast, int expanded)
664 : : {
665 : 208454 : jl_task_t *ct = jl_current_task;
666 [ + + ]: 208454 : if (!jl_is_expr(e)) {
667 [ + + ]: 61127 : if (jl_is_linenode(e)) {
668 : 30573 : jl_lineno = jl_linenode_line(e);
669 : 30573 : jl_value_t *file = jl_linenode_file(e);
670 [ + - ]: 30573 : if (file != jl_nothing) {
671 [ - + ]: 30573 : assert(jl_is_symbol(file));
672 : 30573 : jl_filename = jl_symbol_name((jl_sym_t*)file);
673 : : }
674 : 30573 : return jl_nothing;
675 : : }
676 [ + + ]: 30554 : if (jl_is_symbol(e)) {
677 : 15993 : char *n = jl_symbol_name((jl_sym_t*)e), *n0 = n;
678 [ - + ]: 15993 : while (*n == '_') ++n;
679 [ - + - - ]: 15993 : if (*n == 0 && n > n0)
680 : 0 : jl_eval_errorf(m, "all-underscore identifier used as rvalue");
681 : : }
682 : 30554 : return jl_interpret_toplevel_expr_in(m, e, NULL, NULL);
683 : : }
684 : :
685 : 147327 : jl_expr_t *ex = (jl_expr_t*)e;
686 : :
687 [ + + + - ]: 147327 : if (ex->head == jl_dot_sym && jl_expr_nargs(ex) != 1) {
688 [ - + ]: 1050 : if (jl_expr_nargs(ex) != 2)
689 : 0 : jl_eval_errorf(m, "syntax: malformed \".\" expression");
690 : 1050 : jl_value_t *lhs = jl_exprarg(ex, 0);
691 : 1050 : jl_value_t *rhs = jl_exprarg(ex, 1);
692 : : // only handle `a.b` syntax here, so qualified names can be eval'd in pure contexts
693 [ + - + - ]: 1050 : if (jl_is_quotenode(rhs) && jl_is_symbol(jl_fieldref(rhs, 0))) {
694 : 1050 : return jl_eval_dot_expr(m, lhs, rhs, fast);
695 : : }
696 : : }
697 : :
698 [ - + ]: 146277 : if (ct->ptls->in_pure_callback) {
699 : 0 : jl_error("eval cannot be used in a generated function");
700 : : }
701 : :
702 : 146277 : jl_method_instance_t *mfunc = NULL;
703 : 146277 : jl_code_info_t *thk = NULL;
704 : 146277 : JL_GC_PUSH3(&mfunc, &thk, &ex);
705 : :
706 : 146277 : size_t last_age = ct->world_age;
707 [ + + + + ]: 146277 : if (!expanded && jl_needs_lowering(e)) {
708 : 27348 : ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
709 : 27348 : ex = (jl_expr_t*)jl_expand_with_loc_warn(e, m, jl_filename, jl_lineno);
710 : 27348 : ct->world_age = last_age;
711 : : }
712 [ + - ]: 146277 : jl_sym_t *head = jl_is_expr(ex) ? ex->head : NULL;
713 : :
714 [ + + ]: 146277 : if (head == jl_module_sym) {
715 : 245 : jl_value_t *val = jl_eval_module_expr(m, ex);
716 : 245 : JL_GC_POP();
717 : 245 : return val;
718 : : }
719 [ + + ]: 146032 : else if (head == jl_using_sym) {
720 : 538 : jl_sym_t *name = NULL;
721 : 538 : jl_module_t *from = eval_import_from(m, ex, "using");
722 : 538 : size_t i = 0;
723 [ + + ]: 538 : if (from) {
724 : 283 : i = 1;
725 : 283 : ex = (jl_expr_t*)jl_exprarg(ex, 0);
726 : : }
727 [ + + ]: 2096 : for (; i < jl_expr_nargs(ex); i++) {
728 : 1558 : jl_value_t *a = jl_exprarg(ex, i);
729 [ + - + - ]: 1558 : if (jl_is_expr(a) && ((jl_expr_t*)a)->head == jl_dot_sym) {
730 : 1558 : name = NULL;
731 : 1558 : jl_module_t *import = eval_import_path(m, from, ((jl_expr_t*)a)->args, &name, "using");
732 : 1558 : jl_module_t *u = import;
733 [ + + ]: 1558 : if (name != NULL)
734 : 1416 : u = (jl_module_t*)jl_eval_global_var(import, name);
735 [ + + ]: 1558 : if (from) {
736 : : // `using A: B` syntax
737 : 1234 : jl_module_use(m, import, name);
738 : : }
739 : : else {
740 [ - + ]: 324 : if (!jl_is_module(u))
741 : 0 : jl_eval_errorf(m, "invalid using path: \"%s\" does not name a module",
742 : : jl_symbol_name(name));
743 : : // `using A.B` syntax
744 : 324 : jl_module_using(m, u);
745 [ + + + + ]: 324 : if (m == jl_main_module && name == NULL) {
746 : : // TODO: for now, `using A` in Main also creates an explicit binding for `A`
747 : : // This will possibly be extended to all modules.
748 : 4 : import_module(m, u, NULL);
749 : : }
750 : : }
751 : 1558 : continue;
752 : : }
753 [ # # # # : 0 : else if (from && jl_is_expr(a) && ((jl_expr_t*)a)->head == jl_as_sym && jl_expr_nargs(a) == 2 &&
# # # # ]
754 [ # # # # ]: 0 : jl_is_expr(jl_exprarg(a, 0)) && ((jl_expr_t*)jl_exprarg(a, 0))->head == jl_dot_sym) {
755 : 0 : jl_sym_t *asname = (jl_sym_t*)jl_exprarg(a, 1);
756 [ # # ]: 0 : if (jl_is_symbol(asname)) {
757 : 0 : jl_expr_t *path = (jl_expr_t*)jl_exprarg(a, 0);
758 : 0 : name = NULL;
759 : 0 : jl_module_t *import = eval_import_path(m, from, ((jl_expr_t*)path)->args, &name, "using");
760 [ # # ]: 0 : assert(name);
761 : 0 : check_macro_rename(name, asname, "using");
762 : : // `using A: B as C` syntax
763 : 0 : jl_module_use_as(m, import, name, asname);
764 : 0 : continue;
765 : : }
766 : : }
767 : 0 : jl_eval_errorf(m, "syntax: malformed \"using\" statement");
768 : : }
769 : 538 : JL_GC_POP();
770 : 538 : return jl_nothing;
771 : : }
772 [ + + ]: 145494 : else if (head == jl_import_sym) {
773 : 392 : jl_sym_t *name = NULL;
774 : 392 : jl_module_t *from = eval_import_from(m, ex, "import");
775 : 392 : size_t i = 0;
776 [ + + ]: 392 : if (from) {
777 : 247 : i = 1;
778 : 247 : ex = (jl_expr_t*)jl_exprarg(ex, 0);
779 : : }
780 [ + + ]: 2569 : for (; i < jl_expr_nargs(ex); i++) {
781 : 2177 : jl_value_t *a = jl_exprarg(ex, i);
782 [ + - + - ]: 2177 : if (jl_is_expr(a) && ((jl_expr_t*)a)->head == jl_dot_sym) {
783 : 2177 : name = NULL;
784 : 2177 : jl_module_t *import = eval_import_path(m, from, ((jl_expr_t*)a)->args, &name, "import");
785 [ + + ]: 2177 : if (name == NULL) {
786 : : // `import A` syntax
787 : 56 : import_module(m, import, NULL);
788 : : }
789 : : else {
790 : : // `import A.B` or `import A: B` syntax
791 : 2121 : jl_module_import(m, import, name);
792 : : }
793 : 2177 : continue;
794 : : }
795 [ # # # # : 0 : else if (jl_is_expr(a) && ((jl_expr_t*)a)->head == jl_as_sym && jl_expr_nargs(a) == 2 &&
# # ]
796 [ # # # # ]: 0 : jl_is_expr(jl_exprarg(a, 0)) && ((jl_expr_t*)jl_exprarg(a, 0))->head == jl_dot_sym) {
797 : 0 : jl_sym_t *asname = (jl_sym_t*)jl_exprarg(a, 1);
798 [ # # ]: 0 : if (jl_is_symbol(asname)) {
799 : 0 : jl_expr_t *path = (jl_expr_t*)jl_exprarg(a, 0);
800 : 0 : name = NULL;
801 : 0 : jl_module_t *import = eval_import_path(m, from, ((jl_expr_t*)path)->args, &name, "import");
802 [ # # ]: 0 : if (name == NULL) {
803 : : // `import A as B` syntax
804 : 0 : import_module(m, import, asname);
805 : : }
806 : : else {
807 : 0 : check_macro_rename(name, asname, "import");
808 : : // `import A.B as C` syntax
809 : 0 : jl_module_import_as(m, import, name, asname);
810 : : }
811 : 0 : continue;
812 : : }
813 : : }
814 : 0 : jl_eval_errorf(m, "syntax: malformed \"import\" statement");
815 : : }
816 : 392 : JL_GC_POP();
817 : 392 : return jl_nothing;
818 : : }
819 [ + + ]: 145102 : else if (head == jl_export_sym) {
820 [ + + ]: 9919 : for (size_t i = 0; i < jl_array_len(ex->args); i++) {
821 : 7118 : jl_sym_t *name = (jl_sym_t*)jl_array_ptr_ref(ex->args, i);
822 [ - + ]: 7118 : if (!jl_is_symbol(name))
823 : 0 : jl_eval_errorf(m, "syntax: malformed \"export\" statement");
824 : 7118 : jl_module_export(m, name);
825 : : }
826 : 2801 : JL_GC_POP();
827 : 2801 : return jl_nothing;
828 : : }
829 [ + + ]: 142301 : else if (head == jl_global_sym) {
830 : 7590 : jl_eval_global_expr(m, ex, 0);
831 : 7590 : JL_GC_POP();
832 : 7590 : return jl_nothing;
833 : : }
834 [ + + ]: 134711 : else if (head == jl_const_sym) {
835 : 13261 : jl_sym_t *arg = (jl_sym_t*)jl_exprarg(ex, 0);
836 : : jl_module_t *gm;
837 : : jl_sym_t *gs;
838 [ - + ]: 13261 : if (jl_is_globalref(arg)) {
839 : 0 : gm = jl_globalref_mod(arg);
840 : 0 : gs = jl_globalref_name(arg);
841 : : }
842 : : else {
843 [ - + ]: 13261 : assert(jl_is_symbol(arg));
844 : 13261 : gm = m;
845 : 13261 : gs = (jl_sym_t*)arg;
846 : : }
847 : 13261 : jl_binding_t *b = jl_get_binding_wr(gm, gs, 1);
848 : 13261 : jl_declare_constant(b);
849 : 13261 : JL_GC_POP();
850 : 13261 : return jl_nothing;
851 : : }
852 [ + + ]: 121450 : else if (head == jl_toplevel_sym) {
853 : 16511 : jl_value_t *res = jl_nothing;
854 : : int i;
855 [ + + ]: 50779 : for (i = 0; i < jl_array_len(ex->args); i++) {
856 : 34274 : res = jl_toplevel_eval_flex(m, jl_array_ptr_ref(ex->args, i), fast, 0);
857 : : }
858 : 16505 : JL_GC_POP();
859 : 16505 : return res;
860 : : }
861 [ + - - + ]: 104939 : else if (head == jl_error_sym || head == jl_incomplete_sym) {
862 [ # # ]: 0 : if (jl_expr_nargs(ex) == 0)
863 : 0 : jl_eval_errorf(m, "malformed \"%s\" expression", jl_symbol_name(head));
864 [ # # ]: 0 : if (jl_is_string(jl_exprarg(ex, 0)))
865 : 0 : jl_eval_errorf(m, "syntax: %s", jl_string_data(jl_exprarg(ex, 0)));
866 : 0 : jl_throw(jl_exprarg(ex, 0));
867 : : }
868 [ - + ]: 104939 : else if (jl_is_symbol(ex)) {
869 : 0 : JL_GC_POP();
870 : 0 : return jl_eval_global_var(m, (jl_sym_t*)ex);
871 : : }
872 [ - + ]: 104939 : else if (head == NULL) {
873 : 0 : JL_GC_POP();
874 : 0 : return (jl_value_t*)ex;
875 : : }
876 : :
877 : 104939 : int has_intrinsics = 0, has_defs = 0, has_loops = 0, has_opaque = 0, forced_compile = 0;
878 [ - + ]: 104939 : assert(head == jl_thunk_sym);
879 : 104939 : thk = (jl_code_info_t*)jl_exprarg(ex, 0);
880 [ - + ]: 104939 : assert(jl_is_code_info(thk));
881 [ - + ]: 104939 : assert(jl_typeis(thk->code, jl_array_any_type));
882 : 104939 : body_attributes((jl_array_t*)thk->code, &has_intrinsics, &has_defs, &has_loops, &has_opaque, &forced_compile);
883 : :
884 : : jl_value_t *result;
885 [ + + + + ]: 104939 : if (forced_compile || has_intrinsics ||
886 [ + + + - : 104886 : (!has_defs && fast && has_loops &&
+ + ]
887 [ + - ]: 46 : jl_options.compile_enabled != JL_OPTIONS_COMPILE_OFF &&
888 [ + - + - ]: 92 : jl_options.compile_enabled != JL_OPTIONS_COMPILE_MIN &&
889 [ + - ]: 92 : jl_get_module_compile(m) != JL_OPTIONS_COMPILE_OFF &&
890 : 46 : jl_get_module_compile(m) != JL_OPTIONS_COMPILE_MIN)) {
891 : : // use codegen
892 : 99 : mfunc = method_instance_for_thunk(thk, m);
893 : 99 : jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0);
894 : : // Don't infer blocks containing e.g. method definitions, since it's probably not
895 : : // worthwhile and also unsound (see #24316).
896 : : // TODO: This is still not correct since an `eval` can happen elsewhere, but it
897 : : // helps in common cases.
898 : 99 : size_t world = jl_atomic_load_acquire(&jl_world_counter);
899 : 99 : ct->world_age = world;
900 [ + + + - ]: 99 : if (!has_defs && jl_get_module_infer(m) != 0) {
901 : 66 : (void)jl_type_infer(mfunc, world, 0);
902 : : }
903 : 99 : result = jl_invoke(/*func*/NULL, /*args*/NULL, /*nargs*/0, mfunc);
904 : 99 : ct->world_age = last_age;
905 : : }
906 : : else {
907 : : // use interpreter
908 [ - + ]: 104840 : assert(thk);
909 [ - + ]: 104840 : if (has_opaque) {
910 : 0 : jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0);
911 : : }
912 : 104840 : result = jl_interpret_toplevel_thunk(m, thk);
913 : : }
914 : :
915 : 104933 : JL_GC_POP();
916 : 104933 : return result;
917 : : }
918 : :
919 : 123569 : JL_DLLEXPORT jl_value_t *jl_toplevel_eval(jl_module_t *m, jl_value_t *v)
920 : : {
921 : 123569 : return jl_toplevel_eval_flex(m, v, 1, 0);
922 : : }
923 : :
924 : : // Check module `m` is open for `eval/include`, or throw an error.
925 : 29539 : static void jl_check_open_for(jl_module_t *m, const char* funcname)
926 : : {
927 [ + + + - ]: 29539 : if (jl_options.incremental && jl_generating_output()) {
928 [ + + ]: 8 : if (m != jl_main_module) { // TODO: this was grand-fathered in
929 : 4 : JL_LOCK(&jl_modules_mutex);
930 : 4 : int open = ptrhash_has(&jl_current_modules, (void*)m);
931 [ + - - + ]: 4 : if (!open && jl_module_init_order != NULL) {
932 : 0 : size_t i, l = jl_array_len(jl_module_init_order);
933 [ # # ]: 0 : for (i = 0; i < l; i++) {
934 [ # # ]: 0 : if (m == (jl_module_t*)jl_array_ptr_ref(jl_module_init_order, i)) {
935 : 0 : open = 1;
936 : 0 : break;
937 : : }
938 : : }
939 : : }
940 : 4 : JL_UNLOCK(&jl_modules_mutex);
941 [ + - - + ]: 4 : if (!open && !jl_is__toplevel__mod(m)) {
942 : 0 : const char* name = jl_symbol_name(m->name);
943 : 0 : jl_errorf("Evaluation into the closed module `%s` breaks incremental compilation "
944 : : "because the side effects will not be permanent. "
945 : : "This is likely due to some other module mutating `%s` with `%s` during "
946 : : "precompilation - don't do this.", name, name, funcname);
947 : : }
948 : : }
949 : : }
950 : 29539 : }
951 : :
952 : 0 : JL_DLLEXPORT void jl_check_top_level_effect(jl_module_t *m, char *fname)
953 : : {
954 [ # # ]: 0 : if (jl_current_task->ptls->in_pure_callback)
955 : 0 : jl_errorf("%s cannot be used in a generated function", fname);
956 : 0 : jl_check_open_for(m, fname);
957 : 0 : }
958 : :
959 : 29128 : JL_DLLEXPORT jl_value_t *jl_toplevel_eval_in(jl_module_t *m, jl_value_t *ex)
960 : : {
961 : 29128 : jl_task_t *ct = jl_current_task;
962 [ - + ]: 29128 : if (ct->ptls->in_pure_callback)
963 : 0 : jl_error("eval cannot be used in a generated function");
964 : 29128 : jl_check_open_for(m, "eval");
965 : 29128 : jl_value_t *v = NULL;
966 : 29128 : int last_lineno = jl_lineno;
967 : 29128 : const char *last_filename = jl_filename;
968 : 29128 : jl_lineno = 1;
969 : 29128 : jl_filename = "none";
970 [ + + + + ]: 58250 : JL_TRY {
971 : 29128 : v = jl_toplevel_eval(m, ex);
972 : : }
973 [ + - ]: 4 : JL_CATCH {
974 : 4 : jl_lineno = last_lineno;
975 : 4 : jl_filename = last_filename;
976 : 4 : jl_rethrow();
977 : : }
978 : 29122 : jl_lineno = last_lineno;
979 : 29122 : jl_filename = last_filename;
980 [ - + ]: 29122 : assert(v);
981 : 29122 : return v;
982 : : }
983 : :
984 : 0 : JL_DLLEXPORT jl_value_t *jl_infer_thunk(jl_code_info_t *thk, jl_module_t *m)
985 : : {
986 : 0 : jl_method_instance_t *li = method_instance_for_thunk(thk, m);
987 : 0 : JL_GC_PUSH1(&li);
988 : 0 : jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0);
989 : 0 : jl_task_t *ct = jl_current_task;
990 : 0 : jl_code_info_t *src = jl_type_infer(li, ct->world_age, 0);
991 : 0 : JL_GC_POP();
992 [ # # ]: 0 : if (src)
993 : 0 : return src->rettype;
994 : 0 : return (jl_value_t*)jl_any_type;
995 : : }
996 : :
997 : :
998 : : //------------------------------------------------------------------------------
999 : : // Code loading: combined parse+eval for include()
1000 : :
1001 : : // Parse julia code from the string `text` at top level, attributing it to
1002 : : // `filename`. This is used during bootstrap, but the real Base.include() is
1003 : : // implemented in Julia code.
1004 : 411 : static jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text,
1005 : : jl_value_t *filename)
1006 : : {
1007 [ + - - + ]: 411 : if (!jl_is_string(text) || !jl_is_string(filename)) {
1008 : 0 : jl_errorf("Expected `String`s for `text` and `filename`");
1009 : : }
1010 : 411 : jl_task_t *ct = jl_current_task;
1011 [ - + ]: 411 : if (ct->ptls->in_pure_callback)
1012 : 0 : jl_error("cannot use include inside a generated function");
1013 : 411 : jl_check_open_for(module, "include");
1014 : :
1015 : 411 : jl_value_t *result = jl_nothing;
1016 : 411 : jl_value_t *ast = NULL;
1017 : 411 : jl_value_t *expression = NULL;
1018 : 411 : JL_GC_PUSH3(&ast, &result, &expression);
1019 : :
1020 : 411 : ast = jl_svecref(jl_parse(jl_string_data(text), jl_string_len(text),
1021 : : filename, 1, 0, (jl_value_t*)jl_all_sym), 0);
1022 [ + - - + ]: 411 : if (!jl_is_expr(ast) || ((jl_expr_t*)ast)->head != jl_toplevel_sym) {
1023 : 0 : jl_errorf("jl_parse_all() must generate a top level expression");
1024 : : }
1025 : :
1026 : 411 : int last_lineno = jl_lineno;
1027 : 411 : const char *last_filename = jl_filename;
1028 : 411 : size_t last_age = ct->world_age;
1029 : 411 : int lineno = 0;
1030 : 411 : jl_lineno = 0;
1031 : 411 : jl_filename = jl_string_data(filename);
1032 : 411 : int err = 0;
1033 : :
1034 [ + - + + ]: 822 : JL_TRY {
1035 [ + + ]: 41971 : for (size_t i = 0; i < jl_expr_nargs(ast); i++) {
1036 : 41560 : expression = jl_exprarg(ast, i);
1037 [ + + ]: 41560 : if (jl_is_linenode(expression)) {
1038 : : // filename is already set above.
1039 : 20780 : lineno = jl_linenode_line(expression);
1040 : 20780 : jl_lineno = lineno;
1041 : 20780 : continue;
1042 : : }
1043 : 20780 : expression = jl_expand_with_loc_warn(expression, module,
1044 : : jl_string_data(filename), lineno);
1045 : 20780 : ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
1046 : 20780 : result = jl_toplevel_eval_flex(module, expression, 1, 1);
1047 : : }
1048 : : }
1049 [ # # ]: 0 : JL_CATCH {
1050 : 0 : result = jl_box_long(jl_lineno); // (ab)use result to root error line
1051 : 0 : err = 1;
1052 : 0 : goto finally; // skip jl_restore_excstack
1053 : : }
1054 : 0 : finally:
1055 : 411 : ct->world_age = last_age;
1056 : 411 : jl_lineno = last_lineno;
1057 : 411 : jl_filename = last_filename;
1058 [ - + ]: 411 : if (err) {
1059 [ # # ]: 0 : if (jl_loaderror_type == NULL)
1060 : 0 : jl_rethrow();
1061 : : else
1062 : 0 : jl_rethrow_other(jl_new_struct(jl_loaderror_type, filename, result,
1063 : : jl_current_exception()));
1064 : : }
1065 : 411 : JL_GC_POP();
1066 : 411 : return result;
1067 : : }
1068 : :
1069 : : // Synchronously read content of entire file into a julia String
1070 : 411 : static jl_value_t *jl_file_content_as_string(jl_value_t *filename)
1071 : : {
1072 : 411 : const char *fname = jl_string_data(filename);
1073 : : ios_t f;
1074 [ - + ]: 411 : if (ios_file(&f, fname, 1, 0, 0, 0) == NULL)
1075 : 0 : jl_errorf("File \"%s\" not found", fname);
1076 : 411 : ios_bufmode(&f, bm_none);
1077 : 411 : ios_seek_end(&f);
1078 : 411 : size_t len = ios_pos(&f);
1079 : 411 : jl_value_t *text = jl_alloc_string(len);
1080 : 411 : ios_seek(&f, 0);
1081 [ - + ]: 411 : if (ios_readall(&f, jl_string_data(text), len) != len)
1082 : 0 : jl_errorf("Error reading file \"%s\"", fname);
1083 : 411 : ios_close(&f);
1084 : 411 : return text;
1085 : : }
1086 : :
1087 : : // Load and parse julia code from the file `filename`. Eval the resulting
1088 : : // statements into `module` after applying `mapexpr` to each one.
1089 : 411 : JL_DLLEXPORT jl_value_t *jl_load_(jl_module_t *module, jl_value_t *filename)
1090 : : {
1091 : 411 : jl_value_t *text = jl_file_content_as_string(filename);
1092 : 411 : JL_GC_PUSH1(&text);
1093 : 411 : jl_value_t *result = jl_parse_eval_all(module, text, filename);
1094 : 411 : JL_GC_POP();
1095 : 411 : return result;
1096 : : }
1097 : :
1098 : : // Code loading - julia.h C API with native C types
1099 : :
1100 : : // Parse julia code from `filename` and eval into `module`.
1101 : 4 : JL_DLLEXPORT jl_value_t *jl_load(jl_module_t *module, const char *filename)
1102 : : {
1103 : 4 : jl_value_t *filename_ = NULL;
1104 : 4 : JL_GC_PUSH1(&filename_);
1105 : 4 : filename_ = jl_cstr_to_string(filename);
1106 : 4 : jl_value_t *result = jl_load_(module, filename_);
1107 : 4 : JL_GC_POP();
1108 : 4 : return result;
1109 : : }
1110 : :
1111 : : // Parse julia code from the string `text` of length `len`, attributing it to
1112 : : // `filename`. Eval the resulting statements into `module`.
1113 : 0 : JL_DLLEXPORT jl_value_t *jl_load_file_string(const char *text, size_t len,
1114 : : char *filename, jl_module_t *module)
1115 : : {
1116 : 0 : jl_value_t *text_ = NULL;
1117 : 0 : jl_value_t *filename_ = NULL;
1118 : 0 : JL_GC_PUSH2(&text_, &filename_);
1119 : 0 : text_ = jl_pchar_to_string(text, len);
1120 : 0 : filename_ = jl_cstr_to_string(filename);
1121 : 0 : jl_value_t *result = jl_parse_eval_all(module, text_, filename_);
1122 : 0 : JL_GC_POP();
1123 : 0 : return result;
1124 : : }
1125 : :
1126 : :
1127 : : //--------------------------------------------------
1128 : : // Code loading helpers for bootstrap
1129 : :
1130 : 256 : JL_DLLEXPORT jl_value_t *jl_prepend_cwd(jl_value_t *str)
1131 : : {
1132 : 256 : size_t sz = 1024;
1133 : : char path[1024];
1134 : 256 : int c = uv_cwd(path, &sz);
1135 [ - + ]: 256 : if (c < 0) {
1136 : 0 : jl_errorf("could not get current directory");
1137 : : }
1138 : 256 : path[sz] = '/'; // fix later with normpath if Windows
1139 : 256 : const char *fstr = (const char*)jl_string_data(str);
1140 [ - + ]: 256 : if (strlen(fstr) + sz >= 1024) {
1141 : 0 : jl_errorf("use a bigger buffer for jl_fullpath");
1142 : : }
1143 : 256 : strcpy(path + sz + 1, fstr);
1144 : 256 : return jl_cstr_to_string(path);
1145 : : }
1146 : :
1147 : : #ifdef __cplusplus
1148 : : }
1149 : : #endif
|