LCOV - code coverage report
Current view: top level - src - toplevel.c (source / functions) Hit Total Coverage
Test: [test only] commit 0f242327d2cc9bd130497f44b6350c924185606a Lines: 638 704 90.6 %
Date: 2022-07-16 23:42:53 Functions: 34 35 97.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 418 528 79.2 %

           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                 :        801 : JL_DLLEXPORT void jl_add_standard_imports(jl_module_t *m)
      40                 :            : {
      41                 :        801 :     jl_module_t *base_module = jl_base_relative_to(m);
      42         [ -  + ]:        801 :     assert(base_module != NULL);
      43                 :            :     // using Base
      44                 :        801 :     jl_module_using(m, base_module);
      45                 :        801 : }
      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                 :      14086 : static jl_function_t *jl_module_get_initializer(jl_module_t *m JL_PROPAGATES_ROOT)
      60                 :            : {
      61                 :      14086 :     return (jl_function_t*)jl_get_global(m, jl_symbol("__init__"));
      62                 :            : }
      63                 :            : 
      64                 :            : 
      65                 :      14086 : void jl_module_run_initializer(jl_module_t *m)
      66                 :            : {
      67                 :            :     JL_TIMING(INIT_MODULE);
      68                 :      14086 :     jl_function_t *f = jl_module_get_initializer(m);
      69         [ +  + ]:      14086 :     if (f == NULL)
      70                 :        539 :         return;
      71                 :      13547 :     jl_task_t *ct = jl_current_task;
      72                 :      13547 :     size_t last_age = ct->world_age;
      73   [ +  +  +  + ]:      27093 :     JL_TRY {
      74                 :      13547 :         ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
      75                 :      13547 :         jl_apply(&f, 1);
      76                 :      13546 :         ct->world_age = last_age;
      77                 :            :     }
      78         [ +  - ]:          1 :     JL_CATCH {
      79         [ -  + ]:          1 :         if (jl_initerror_type == NULL) {
      80                 :          0 :             jl_rethrow();
      81                 :            :         }
      82                 :            :         else {
      83                 :          1 :             jl_rethrow_other(jl_new_struct(jl_initerror_type, m->name,
      84                 :            :                                            jl_current_exception()));
      85                 :            :         }
      86                 :            :     }
      87                 :            : }
      88                 :            : 
      89                 :        126 : static void jl_register_root_module(jl_module_t *m)
      90                 :            : {
      91                 :            :     static jl_value_t *register_module_func = NULL;
      92         [ -  + ]:        126 :     assert(jl_base_module);
      93         [ +  + ]:        126 :     if (register_module_func == NULL)
      94                 :         87 :         register_module_func = jl_get_global(jl_base_module, jl_symbol("register_root_module"));
      95         [ -  + ]:        126 :     assert(register_module_func);
      96                 :            :     jl_value_t *args[2];
      97                 :        126 :     args[0] = register_module_func;
      98                 :        126 :     args[1] = (jl_value_t*)m;
      99                 :        126 :     jl_apply(args, 2);
     100                 :        126 : }
     101                 :            : 
     102                 :         88 : jl_array_t *jl_get_loaded_modules(void)
     103                 :            : {
     104                 :            :     static jl_value_t *loaded_modules_array = NULL;
     105   [ +  +  +  + ]:         88 :     if (loaded_modules_array == NULL && jl_base_module != NULL)
     106                 :         83 :         loaded_modules_array = jl_get_global(jl_base_module, jl_symbol("loaded_modules_array"));
     107         [ +  + ]:         88 :     if (loaded_modules_array != NULL)
     108                 :         85 :         return (jl_array_t*)jl_call0((jl_function_t*)loaded_modules_array);
     109                 :          3 :     return NULL;
     110                 :            : }
     111                 :            : 
     112                 :        863 : static int jl_is__toplevel__mod(jl_module_t *mod)
     113                 :            : {
     114   [ +  +  +  + ]:       1716 :     return jl_base_module &&
     115                 :        853 :         (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                 :        777 : static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex)
     120                 :            : {
     121                 :        777 :     jl_task_t *ct = jl_current_task;
     122         [ -  + ]:        777 :     assert(ex->head == jl_module_sym);
     123   [ +  -  -  + ]:        777 :     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         [ +  + ]:        777 :     if (((jl_expr_t *)(jl_exprarg(ex, 2)))->head != jl_symbol("block")) {
     128                 :          3 :         jl_error("syntax: module expression third argument must be a block");
     129                 :            :     }
     130                 :            : 
     131                 :        774 :     int std_imports = (jl_exprarg(ex, 0) == jl_true);
     132                 :        774 :     jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1);
     133         [ -  + ]:        774 :     if (!jl_is_symbol(name)) {
     134                 :          0 :         jl_type_error("module", (jl_value_t*)jl_symbol_type, (jl_value_t*)name);
     135                 :            :     }
     136                 :            : 
     137                 :        774 :     jl_module_t *newm = jl_new_module(name);
     138                 :        774 :     jl_value_t *form = (jl_value_t*)newm;
     139                 :        774 :     JL_GC_PUSH1(&form);
     140                 :        774 :     JL_LOCK(&jl_modules_mutex);
     141                 :        774 :     ptrhash_put(&jl_current_modules, (void*)newm, (void*)((uintptr_t)HT_NOTFOUND + 1));
     142                 :        774 :     JL_UNLOCK(&jl_modules_mutex);
     143                 :            : 
     144                 :        774 :     jl_module_t *old_toplevel_module = jl_precompile_toplevel_module;
     145                 :            : 
     146                 :            :     // copy parent environment info into submodule
     147                 :        774 :     newm->uuid = parent_module->uuid;
     148         [ +  + ]:        774 :     if (jl_is__toplevel__mod(parent_module)) {
     149                 :        126 :         newm->parent = newm;
     150                 :        126 :         jl_register_root_module(newm);
     151         [ +  + ]:        126 :         if (jl_options.incremental) {
     152                 :         82 :             jl_precompile_toplevel_module = newm;
     153                 :            :         }
     154                 :            :     }
     155                 :            :     else {
     156                 :        648 :         newm->parent = parent_module;
     157                 :        648 :         jl_binding_t *b = jl_get_binding_wr(parent_module, name, 1);
     158                 :        648 :         jl_declare_constant(b);
     159                 :        648 :         jl_value_t *old = NULL;
     160         [ -  + ]:        648 :         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                 :        648 :         jl_gc_wb_binding(b, newm);
     170         [ -  + ]:        648 :         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   [ +  +  +  + ]:        774 :     if (parent_module == jl_main_module && name == jl_symbol("Base")) {
     180                 :            :         // pick up Base module during bootstrap
     181                 :          1 :         jl_base_module = newm;
     182                 :            :     }
     183                 :            : 
     184                 :        774 :     size_t last_age = ct->world_age;
     185                 :            : 
     186                 :            :     // add standard imports unless baremodule
     187         [ +  + ]:        774 :     if (std_imports) {
     188         [ +  + ]:        742 :         if (jl_base_module != NULL) {
     189                 :        736 :             jl_add_standard_imports(newm);
     190                 :            :         }
     191                 :            :         // add `eval` function
     192                 :        742 :         form = jl_call_scm_on_ast("module-default-defs", (jl_value_t*)ex, newm);
     193                 :        742 :         jl_toplevel_eval_flex(newm, form, 0, 1);
     194                 :        742 :         form = NULL;
     195                 :            :     }
     196                 :            : 
     197                 :        774 :     jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 2))->args;
     198         [ +  + ]:      32132 :     for (int i = 0; i < jl_array_len(exprs); i++) {
     199                 :            :         // process toplevel form
     200                 :      31370 :         ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
     201                 :      31370 :         form = jl_expand_stmt_with_loc(jl_array_ptr_ref(exprs, i), newm, jl_filename, jl_lineno);
     202                 :      31370 :         ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
     203                 :      31370 :         (void)jl_toplevel_eval_flex(newm, form, 1, 1);
     204                 :            :     }
     205                 :        762 :     newm->primary_world = jl_atomic_load_acquire(&jl_world_counter);
     206                 :        762 :     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                 :        762 :     JL_LOCK(&jl_modules_mutex);
     230                 :        762 :     uintptr_t *refcnt = (uintptr_t*)ptrhash_bp(&jl_current_modules, (void*)newm);
     231         [ -  + ]:        762 :     assert(*refcnt > (uintptr_t)HT_NOTFOUND);
     232                 :        762 :     *refcnt -= 1;
     233                 :            :     // newm should be reachable from somewhere else by now
     234                 :            : 
     235         [ +  + ]:        762 :     if (jl_module_init_order == NULL)
     236                 :        121 :         jl_module_init_order = jl_alloc_vec_any(0);
     237                 :        762 :     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                 :        762 :     form = NULL;
     243         [ +  + ]:        762 :     if (!jl_generating_output()) {
     244         [ +  + ]:        545 :         if (!ptrhash_has(&jl_current_modules, (void*)newm->parent)) {
     245                 :        513 :             size_t i, l = jl_array_len(jl_module_init_order);
     246                 :        513 :             size_t ns = 0;
     247                 :        513 :             form = (jl_value_t*)jl_alloc_vec_any(0);
     248         [ +  + ]:       1065 :             for (i = 0; i < l; i++) {
     249                 :        552 :                 jl_module_t *m = (jl_module_t*)jl_array_ptr_ref(jl_module_init_order, i);
     250         [ +  + ]:        552 :                 if (jl_is_submodule(m, newm)) {
     251                 :        541 :                     jl_array_ptr_1d_push((jl_array_t*)form, (jl_value_t*)m);
     252                 :            :                 }
     253         [ -  + ]:         11 :                 else if (ns++ != i) {
     254                 :          0 :                     jl_array_ptr_set(jl_module_init_order, ns - 1, (jl_value_t*)m);
     255                 :            :                 }
     256                 :            :             }
     257         [ +  - ]:        513 :             if (ns < l)
     258                 :        513 :                 jl_array_del_end(jl_module_init_order, l - ns);
     259                 :            :         }
     260                 :            :     }
     261                 :        762 :     JL_UNLOCK(&jl_modules_mutex);
     262                 :            : 
     263         [ +  + ]:        762 :     if (form) {
     264                 :        513 :         size_t i, l = jl_array_len(form);
     265         [ +  + ]:       1053 :         for (i = 0; i < l; i++) {
     266                 :        541 :             jl_module_t *m = (jl_module_t*)jl_array_ptr_ref(form, i);
     267                 :            :             JL_GC_PROMISE_ROOTED(m);
     268                 :        541 :             jl_module_run_initializer(m);
     269                 :            :         }
     270                 :            :     }
     271                 :            : 
     272                 :        761 :     jl_precompile_toplevel_module = old_toplevel_module;
     273                 :            : 
     274                 :        761 :     JL_GC_POP();
     275                 :        761 :     return (jl_value_t*)newm;
     276                 :            : }
     277                 :            : 
     278                 :       3028 : static jl_value_t *jl_eval_dot_expr(jl_module_t *m, jl_value_t *x, jl_value_t *f, int fast)
     279                 :            : {
     280                 :       3028 :     jl_task_t *ct = jl_current_task;
     281                 :            :     jl_value_t **args;
     282                 :       3028 :     JL_GC_PUSHARGS(args, 3);
     283                 :       3028 :     args[1] = jl_toplevel_eval_flex(m, x, fast, 0);
     284                 :       3028 :     args[2] = jl_toplevel_eval_flex(m, f, fast, 0);
     285         [ +  + ]:       3028 :     if (jl_is_module(args[1])) {
     286         [ -  + ]:       3012 :         JL_TYPECHK(getglobal, symbol, args[2]);
     287                 :       3012 :         args[0] = jl_eval_global_var((jl_module_t*)args[1], (jl_sym_t*)args[2]);
     288                 :            :     }
     289                 :            :     else {
     290                 :         16 :         args[0] = jl_eval_global_var(jl_base_relative_to(m), jl_symbol("getproperty"));
     291                 :         16 :         size_t last_age = ct->world_age;
     292                 :         16 :         ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
     293                 :         16 :         args[0] = jl_apply(args, 3);
     294                 :         16 :         ct->world_age = last_age;
     295                 :            :     }
     296                 :       3027 :     JL_GC_POP();
     297                 :       3027 :     return args[0];
     298                 :            : }
     299                 :            : 
     300                 :      28987 : 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                 :      28987 :     size_t i, l = jl_array_len(ex->args);
     303         [ +  + ]:      57976 :     for (i = 0; i < l; i++) {
     304                 :      28989 :         jl_value_t *arg = jl_exprarg(ex, i);
     305                 :            :         jl_module_t *gm;
     306                 :            :         jl_sym_t *gs;
     307         [ -  + ]:      28989 :         if (jl_is_globalref(arg)) {
     308                 :          0 :             gm = jl_globalref_mod(arg);
     309                 :          0 :             gs = jl_globalref_name(arg);
     310                 :            :         }
     311                 :            :         else {
     312         [ -  + ]:      28989 :             assert(jl_is_symbol(arg));
     313                 :      28989 :             gm = m;
     314                 :      28989 :             gs = (jl_sym_t*)arg;
     315                 :            :         }
     316         [ +  + ]:      28989 :         if (!jl_binding_resolved_p(gm, gs)) {
     317                 :      26335 :             jl_binding_t *b = jl_get_binding_wr(gm, gs, 1);
     318         [ +  + ]:      26335 :             if (set_type) {
     319                 :         32 :                 jl_value_t *old_ty = NULL;
     320                 :            :                 // maybe set the type too, perhaps
     321                 :         32 :                 jl_atomic_cmpswap_relaxed(&b->ty, &old_ty, (jl_value_t*)jl_any_type);
     322                 :            :             }
     323                 :            :         }
     324                 :            :     }
     325                 :      28987 : }
     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                 :   10046200 : JL_DLLEXPORT jl_module_t *jl_base_relative_to(jl_module_t *m)
     332                 :            : {
     333                 :            :     for (;;) {
     334         [ +  + ]:   10046200 :         if (m->istopmod)
     335                 :    8468300 :             return m;
     336         [ +  + ]:    1577940 :         if (m == m->parent)
     337                 :     720297 :             break;
     338                 :     857646 :         m = m->parent;
     339                 :            :     }
     340                 :     720297 :     return jl_top_module;
     341                 :            : }
     342                 :            : 
     343                 :    3251280 : static void expr_attributes(jl_value_t *v, int *has_intrinsics, int *has_defs, int *has_opaque)
     344                 :            : {
     345         [ +  + ]:    3251280 :     if (!jl_is_expr(v))
     346                 :     762487 :         return;
     347                 :    2488790 :     jl_expr_t *e = (jl_expr_t*)v;
     348                 :    2488790 :     jl_sym_t *head = e->head;
     349   [ +  +  +  + ]:    2488790 :     if (head == jl_toplevel_sym || head == jl_thunk_sym) {
     350                 :      56154 :         return;
     351                 :            :     }
     352         [ +  + ]:    2432640 :     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                 :      28684 :         return;
     356                 :            :     }
     357   [ +  +  +  + ]:    2403950 :     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                 :      44941 :         *has_defs = 1;
     361                 :      44941 :         return;
     362                 :            :     }
     363   [ +  +  +  + ]:    2359010 :     else if (head == jl_method_sym || jl_is_toplevel_only_expr(v)) {
     364                 :     109822 :         *has_defs = 1;
     365                 :            :     }
     366         [ +  + ]:    2249190 :     else if (head == jl_cfunction_sym) {
     367                 :         66 :         *has_intrinsics = 1;
     368                 :         66 :         return;
     369                 :            :     }
     370         [ +  + ]:    2249120 :     else if (head == jl_foreigncall_sym) {
     371                 :        325 :         *has_intrinsics = 1;
     372                 :        325 :         return;
     373                 :            :     }
     374         [ +  + ]:    2248800 :     else if (head == jl_new_opaque_closure_sym) {
     375                 :         19 :         *has_opaque = 1;
     376                 :         19 :         return;
     377                 :            :     }
     378   [ +  +  +  - ]:    2248780 :     else if (head == jl_call_sym && jl_expr_nargs(e) > 0) {
     379                 :    1539760 :         jl_value_t *called = NULL;
     380                 :    1539760 :         jl_value_t *f = jl_exprarg(e, 0);
     381         [ +  + ]:    1539750 :         if (jl_is_globalref(f)) {
     382                 :    1257360 :             jl_module_t *mod = jl_globalref_mod(f);
     383                 :    1257360 :             jl_sym_t *name = jl_globalref_name(f);
     384         [ +  + ]:    1257360 :             if (jl_binding_resolved_p(mod, name)) {
     385                 :    1256450 :                 jl_binding_t *b = jl_get_binding(mod, name);
     386   [ +  -  +  - ]:    1256460 :                 if (b && b->constp) {
     387                 :    1256460 :                     called = jl_atomic_load_relaxed(&b->value);
     388                 :            :                 }
     389                 :            :             }
     390                 :            :         }
     391         [ +  + ]:     282395 :         else if (jl_is_quotenode(f)) {
     392                 :          1 :             called = jl_quotenode_value(f);
     393                 :            :         }
     394         [ +  + ]:    1539770 :         if (called != NULL) {
     395   [ +  +  +  + ]:    1256460 :             if (jl_is_intrinsic(called) && jl_unbox_int32(called) == (int)llvmcall) {
     396                 :          1 :                 *has_intrinsics = 1;
     397                 :            :             }
     398         [ +  + ]:    1256460 :             if (called == jl_builtin__typebody) {
     399                 :      26121 :                 *has_defs = 1;
     400                 :            :             }
     401                 :            :         }
     402                 :    1539770 :         return;
     403                 :            :     }
     404                 :            :     int i;
     405         [ +  + ]:    2167720 :     for (i = 0; i < jl_array_len(e->args); i++) {
     406                 :    1348870 :         jl_value_t *a = jl_exprarg(e, i);
     407         [ +  + ]:    1348870 :         if (jl_is_expr(a))
     408                 :     223723 :             expr_attributes(a, has_intrinsics, has_defs, has_opaque);
     409                 :            :     }
     410                 :            : }
     411                 :            : 
     412                 :        617 : int jl_code_requires_compiler(jl_code_info_t *src)
     413                 :            : {
     414                 :        617 :     jl_array_t *body = src->code;
     415         [ -  + ]:        617 :     assert(jl_typeis(body, jl_array_any_type));
     416                 :            :     size_t i;
     417                 :        617 :     int has_intrinsics = 0, has_defs = 0, has_opaque = 0;
     418         [ -  + ]:        617 :     if (jl_has_meta(body, jl_force_compile_sym))
     419                 :          0 :         return 1;
     420         [ +  + ]:       9175 :     for(i=0; i < jl_array_len(body); i++) {
     421                 :       8578 :         jl_value_t *stmt = jl_array_ptr_ref(body,i);
     422                 :       8578 :         expr_attributes(stmt, &has_intrinsics, &has_defs, &has_opaque);
     423         [ +  + ]:       8578 :         if (has_intrinsics)
     424                 :         20 :             return 1;
     425                 :            :     }
     426                 :        597 :     return 0;
     427                 :            : }
     428                 :            : 
     429                 :     156289 : 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                 :     156289 :     *has_loops = 0;
     433         [ +  + ]:    3175290 :     for(i=0; i < jl_array_len(body); i++) {
     434                 :    3018980 :         jl_value_t *stmt = jl_array_ptr_ref(body,i);
     435         [ +  + ]:    3018980 :         if (!*has_loops) {
     436         [ +  + ]:    2600270 :             if (jl_is_gotonode(stmt)) {
     437         [ +  + ]:     156903 :                 if (jl_gotonode_label(stmt) <= i)
     438                 :       1765 :                     *has_loops = 1;
     439                 :            :             }
     440         [ +  + ]:    2443370 :             else if (jl_is_gotoifnot(stmt)) {
     441         [ +  + ]:     138194 :                 if (jl_gotoifnot_label(stmt) <= i)
     442                 :          4 :                     *has_loops = 1;
     443                 :            :             }
     444                 :            :         }
     445                 :    3018980 :         expr_attributes(stmt, has_intrinsics, has_defs, has_opaque);
     446                 :            :     }
     447                 :     156314 :     *forced_compile = jl_has_meta(body, jl_force_compile_sym);
     448                 :     156293 : }
     449                 :            : 
     450                 :       1706 : 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                 :       1706 :     int build_mode = jl_generating_output();
     454                 :       1706 :     jl_module_t *m = NULL;
     455                 :       1706 :     jl_task_t *ct = jl_current_task;
     456   [ +  +  +  - ]:       1706 :     if (require_func == NULL && jl_base_module != NULL) {
     457                 :        222 :         require_func = jl_get_global(jl_base_module, jl_symbol("require"));
     458                 :            :     }
     459         [ +  - ]:       1706 :     if (require_func != NULL) {
     460                 :       1706 :         size_t last_age = ct->world_age;
     461         [ +  + ]:       1706 :         ct->world_age = (build_mode ? jl_base_module->primary_world : jl_atomic_load_acquire(&jl_world_counter));
     462                 :            :         jl_value_t *reqargs[3];
     463                 :       1706 :         reqargs[0] = require_func;
     464                 :       1706 :         reqargs[1] = (jl_value_t*)mod;
     465                 :       1706 :         reqargs[2] = (jl_value_t*)var;
     466                 :       1706 :         m = (jl_module_t*)jl_apply(reqargs, 3);
     467                 :       1699 :         ct->world_age = last_age;
     468                 :            :     }
     469   [ +  -  -  + ]:       1699 :     if (m == NULL || !jl_is_module(m)) {
     470                 :          0 :         jl_errorf("failed to load module %s", jl_symbol_name(var));
     471                 :            :     }
     472                 :       1699 :     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                 :       5795 : 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         [ -  + ]:       5795 :     if (jl_array_len(args) == 0)
     482                 :          0 :         jl_errorf("malformed \"%s\" statement", keyword);
     483                 :       5795 :     jl_sym_t *var = (jl_sym_t*)jl_array_ptr_ref(args, 0);
     484                 :       5795 :     size_t i = 1;
     485                 :       5795 :     jl_module_t *m = NULL;
     486                 :       5795 :     *name = NULL;
     487         [ -  + ]:       5795 :     if (!jl_is_symbol(var))
     488                 :          0 :         jl_type_error(keyword, (jl_value_t*)jl_symbol_type, (jl_value_t*)var);
     489                 :            : 
     490         [ +  + ]:       5795 :     if (from != NULL) {
     491                 :       3066 :         m = from;
     492                 :       3066 :         i = 0;
     493                 :            :     }
     494         [ +  + ]:       2729 :     else if (var != jl_dot_sym) {
     495                 :            :         // `A.B`: call the loader to obtain the root A in the current environment.
     496   [ +  -  +  + ]:       2225 :         if (jl_core_module && var == jl_core_module->name) {
     497                 :         79 :             m = jl_core_module;
     498                 :            :         }
     499   [ +  -  +  + ]:       2146 :         else if (jl_base_module && var == jl_base_module->name) {
     500                 :        440 :             m = jl_base_module;
     501                 :            :         }
     502                 :            :         else {
     503                 :       1706 :             m = call_require(where, var);
     504                 :            :         }
     505         [ +  + ]:       2218 :         if (i == jl_array_len(args))
     506                 :       1941 :             return m;
     507                 :            :     }
     508                 :            :     else {
     509                 :            :         // `.A.B.C`: strip off leading dots by following parent links
     510                 :        504 :         m = where;
     511                 :            :         while (1) {
     512         [ +  + ]:        695 :             if (i >= jl_array_len(args))
     513                 :          1 :                 jl_error("invalid module path");
     514                 :        694 :             var = (jl_sym_t*)jl_array_ptr_ref(args, i);
     515         [ +  + ]:        694 :             if (var != jl_dot_sym)
     516                 :        503 :                 break;
     517                 :        191 :             i++;
     518         [ -  + ]:        191 :             assert(m);
     519                 :        191 :             m = m->parent;
     520                 :            :         }
     521                 :            :     }
     522                 :            : 
     523                 :            :     while (1) {
     524                 :       3938 :         var = (jl_sym_t*)jl_array_ptr_ref(args, i);
     525         [ -  + ]:       3938 :         if (!jl_is_symbol(var))
     526                 :          0 :             jl_type_error(keyword, (jl_value_t*)jl_symbol_type, (jl_value_t*)var);
     527         [ -  + ]:       3938 :         if (var == jl_dot_sym)
     528                 :          0 :             jl_errorf("invalid %s path: \".\" in identifier path", keyword);
     529         [ +  + ]:       3938 :         if (i == jl_array_len(args)-1)
     530                 :       3846 :             break;
     531                 :         92 :         m = (jl_module_t*)jl_eval_global_var(m, var);
     532                 :            :         JL_GC_PROMISE_ROOTED(m);
     533         [ -  + ]:         92 :         if (!jl_is_module(m))
     534                 :          0 :             jl_errorf("invalid %s path: \"%s\" does not name a module", keyword, jl_symbol_name(var));
     535                 :         92 :         i++;
     536                 :            :     }
     537                 :       3846 :     *name = var;
     538                 :       3846 :     return m;
     539                 :            : }
     540                 :            : 
     541                 :   26950200 : int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT
     542                 :            : {
     543         [ +  + ]:   53900100 :     return jl_is_expr(e) &&
     544         [ +  # ]:   26949900 :         (((jl_expr_t*)e)->head == jl_module_sym ||
     545         [ +  + ]:   26950000 :          ((jl_expr_t*)e)->head == jl_import_sym ||
     546         [ +  + ]:   26949900 :          ((jl_expr_t*)e)->head == jl_using_sym ||
     547         [ +  + ]:   26949800 :          ((jl_expr_t*)e)->head == jl_export_sym ||
     548         [ +  + ]:   26949800 :          ((jl_expr_t*)e)->head == jl_thunk_sym ||
     549         [ +  + ]:   26893600 :          ((jl_expr_t*)e)->head == jl_global_sym ||
     550         [ +  + ]:   26864800 :          ((jl_expr_t*)e)->head == jl_const_sym ||
     551         [ +  - ]:   26833200 :          ((jl_expr_t*)e)->head == jl_toplevel_sym ||
     552         [ +  - ]:   26833200 :          ((jl_expr_t*)e)->head == jl_error_sym ||
     553         [ +  + ]:   26833200 :          ((jl_expr_t*)e)->head == jl_incomplete_sym);
     554                 :            : }
     555                 :            : 
     556                 :     220239 : int jl_needs_lowering(jl_value_t *e) JL_NOTSAFEPOINT
     557                 :            : {
     558         [ -  + ]:     220239 :     if (!jl_is_expr(e))
     559                 :          0 :         return 0;
     560                 :     220239 :     jl_expr_t *ex = (jl_expr_t*)e;
     561                 :     220239 :     jl_sym_t *head = ex->head;
     562   [ +  +  +  +  :     220239 :     if (head == jl_module_sym || head == jl_import_sym || head == jl_using_sym ||
                   +  + ]
     563   [ +  +  +  +  :     218251 :         head == jl_export_sym || head == jl_thunk_sym || head == jl_toplevel_sym ||
                   +  + ]
     564   [ +  +  +  +  :     133665 :         head == jl_error_sym || head == jl_incomplete_sym || head == jl_method_sym) {
                   -  + ]
     565                 :      86588 :         return 0;
     566                 :            :     }
     567   [ +  +  +  + ]:     133651 :     if (head == jl_global_sym || head == jl_const_sym) {
     568                 :      63122 :         size_t i, l = jl_array_len(ex->args);
     569         [ +  + ]:     123459 :         for (i = 0; i < l; i++) {
     570                 :      63124 :             jl_value_t *a = jl_exprarg(ex, i);
     571   [ +  +  +  - ]:      63124 :             if (!jl_is_symbol(a) && !jl_is_globalref(a))
     572                 :       2787 :                 return 1;
     573                 :            :         }
     574                 :      60335 :         return 0;
     575                 :            :     }
     576                 :      70529 :     return 1;
     577                 :            : }
     578                 :            : 
     579                 :       1141 : static jl_method_instance_t *method_instance_for_thunk(jl_code_info_t *src, jl_module_t *module)
     580                 :            : {
     581                 :       1141 :     jl_method_instance_t *li = jl_new_method_instance_uninit();
     582                 :       1141 :     li->uninferred = (jl_value_t*)src;
     583                 :       1141 :     li->specTypes = (jl_value_t*)jl_emptytuple_type;
     584                 :       1141 :     li->def.module = module;
     585                 :       1141 :     return li;
     586                 :            : }
     587                 :            : 
     588                 :        382 : static void import_module(jl_module_t *JL_NONNULL m, jl_module_t *import, jl_sym_t *asname)
     589                 :            : {
     590         [ -  + ]:        382 :     assert(m);
     591         [ +  - ]:        382 :     jl_sym_t *name = asname ? asname : import->name;
     592                 :            :     jl_binding_t *b;
     593         [ +  + ]:        382 :     if (jl_binding_resolved_p(m, name)) {
     594                 :         46 :         b = jl_get_binding(m, name);
     595                 :         46 :         jl_value_t *bv = jl_atomic_load_relaxed(&b->value);
     596   [ -  +  -  -  :         46 :         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                 :        336 :         b = jl_get_binding_wr(m, name, 1);
     603                 :        336 :         b->imported = 1;
     604                 :            :     }
     605         [ +  + ]:        382 :     if (!b->constp) {
     606                 :            :         // TODO: constp is not threadsafe
     607                 :        336 :         jl_atomic_store_release(&b->value, (jl_value_t*)import);
     608                 :        336 :         b->constp = 1;
     609                 :        336 :         jl_gc_wb(m, (jl_value_t*)import);
     610                 :            :     }
     611                 :        382 : }
     612                 :            : 
     613                 :            : // in `import A.B: x, y, ...`, evaluate the `A.B` part if it exists
     614                 :       2158 : static jl_module_t *eval_import_from(jl_module_t *m JL_PROPAGATES_ROOT, jl_expr_t *ex, const char *keyword)
     615                 :            : {
     616   [ +  +  +  + ]:       2158 :     if (jl_expr_nargs(ex) == 1 && jl_is_expr(jl_exprarg(ex, 0))) {
     617                 :       1710 :         jl_expr_t *fr = (jl_expr_t*)jl_exprarg(ex, 0);
     618         [ +  + ]:       1710 :         if (fr->head == jl_colon_sym) {
     619   [ +  -  +  - ]:        701 :             if (jl_expr_nargs(fr) > 0 && jl_is_expr(jl_exprarg(fr, 0))) {
     620                 :        701 :                 jl_expr_t *path = (jl_expr_t*)jl_exprarg(fr, 0);
     621         [ +  - ]:        701 :                 if (((jl_expr_t*)path)->head == jl_dot_sym) {
     622                 :        701 :                     jl_sym_t *name = NULL;
     623                 :        701 :                     jl_module_t *from = eval_import_path(m, NULL, path->args, &name, keyword);
     624         [ +  + ]:        701 :                     if (name != NULL) {
     625                 :        264 :                         from = (jl_module_t*)jl_eval_global_var(from, name);
     626         [ -  + ]:        264 :                         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                 :        701 :                     return from;
     630                 :            :                 }
     631                 :            :             }
     632                 :          0 :             jl_errorf("malformed \"%s:\" statement", keyword);
     633                 :            :         }
     634                 :            :     }
     635                 :       1457 :     return NULL;
     636                 :            : }
     637                 :            : 
     638                 :         16 : static void check_macro_rename(jl_sym_t *from, jl_sym_t *to, const char *keyword)
     639                 :            : {
     640                 :         16 :     char *n1 = jl_symbol_name(from), *n2 = jl_symbol_name(to);
     641   [ +  +  +  + ]:         16 :     if (n1[0] == '@' && n2[0] != '@')
     642                 :          2 :         jl_errorf("cannot rename macro \"%s\" to non-macro \"%s\" in \"%s\"", n1, n2, keyword);
     643   [ +  +  +  + ]:         14 :     if (n1[0] != '@' && n2[0] == '@')
     644                 :          2 :         jl_errorf("cannot rename non-macro \"%s\" to macro \"%s\" in \"%s\"", n1, n2, keyword);
     645                 :         12 : }
     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                 :         36 : static void jl_eval_errorf(jl_module_t *m, const char* fmt, ...)
     651                 :            : {
     652                 :         36 :     jl_value_t *throw_ex = (jl_value_t*)jl_exprn(jl_call_sym, 2);
     653                 :         36 :     JL_GC_PUSH1(&throw_ex);
     654                 :         36 :     jl_exprargset(throw_ex, 0, jl_builtin_throw);
     655                 :            :     va_list args;
     656                 :         36 :     va_start(args, fmt);
     657                 :         36 :     jl_exprargset(throw_ex, 1, jl_vexceptionf(jl_errorexception_type, fmt, args));
     658                 :         36 :     va_end(args);
     659                 :         36 :     jl_toplevel_eval_flex(m, throw_ex, 0, 0);
     660                 :          0 :     JL_GC_POP();
     661                 :          0 : }
     662                 :            : 
     663                 :     463064 : jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_value_t *e, int fast, int expanded)
     664                 :            : {
     665                 :     463064 :     jl_task_t *ct = jl_current_task;
     666         [ +  + ]:     463064 :     if (!jl_is_expr(e)) {
     667         [ +  + ]:     211450 :         if (jl_is_linenode(e)) {
     668                 :      43446 :             jl_lineno = jl_linenode_line(e);
     669                 :      43446 :             jl_value_t *file = jl_linenode_file(e);
     670         [ +  - ]:      43446 :             if (file != jl_nothing) {
     671         [ -  + ]:      43446 :                 assert(jl_is_symbol(file));
     672                 :      43446 :                 jl_filename = jl_symbol_name((jl_sym_t*)file);
     673                 :            :             }
     674                 :      43446 :             return jl_nothing;
     675                 :            :         }
     676         [ +  + ]:     168004 :         if (jl_is_symbol(e)) {
     677                 :      79810 :             char *n = jl_symbol_name((jl_sym_t*)e), *n0 = n;
     678         [ -  + ]:      79810 :             while (*n == '_') ++n;
     679   [ +  +  -  + ]:      79810 :             if (*n == 0 && n > n0)
     680                 :          0 :                 jl_eval_errorf(m, "all-underscore identifier used as rvalue");
     681                 :            :         }
     682                 :     168004 :         return jl_interpret_toplevel_expr_in(m, e, NULL, NULL);
     683                 :            :     }
     684                 :            : 
     685                 :     251614 :     jl_expr_t *ex = (jl_expr_t*)e;
     686                 :            : 
     687   [ +  +  +  + ]:     251614 :     if (ex->head == jl_dot_sym && jl_expr_nargs(ex) != 1) {
     688         [ -  + ]:       3031 :         if (jl_expr_nargs(ex) != 2)
     689                 :          0 :             jl_eval_errorf(m, "syntax: malformed \".\" expression");
     690                 :       3031 :         jl_value_t *lhs = jl_exprarg(ex, 0);
     691                 :       3031 :         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   [ +  +  +  + ]:       3031 :         if (jl_is_quotenode(rhs) && jl_is_symbol(jl_fieldref(rhs, 0))) {
     694                 :       3028 :             return jl_eval_dot_expr(m, lhs, rhs, fast);
     695                 :            :         }
     696                 :            :     }
     697                 :            : 
     698         [ -  + ]:     248586 :     if (ct->ptls->in_pure_callback) {
     699                 :          0 :         jl_error("eval cannot be used in a generated function");
     700                 :            :     }
     701                 :            : 
     702                 :     248586 :     jl_method_instance_t *mfunc = NULL;
     703                 :     248586 :     jl_code_info_t *thk = NULL;
     704                 :     248586 :     JL_GC_PUSH3(&mfunc, &thk, &ex);
     705                 :            : 
     706                 :     248586 :     size_t last_age = ct->world_age;
     707   [ +  +  +  + ]:     248586 :     if (!expanded && jl_needs_lowering(e)) {
     708                 :      73316 :         ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
     709                 :      73316 :         ex = (jl_expr_t*)jl_expand_with_loc_warn(e, m, jl_filename, jl_lineno);
     710                 :      73308 :         ct->world_age = last_age;
     711                 :            :     }
     712         [ +  + ]:     248578 :     jl_sym_t *head = jl_is_expr(ex) ? ex->head : NULL;
     713                 :            : 
     714         [ +  + ]:     248578 :     if (head == jl_module_sym) {
     715                 :        777 :         jl_value_t *val = jl_eval_module_expr(m, ex);
     716                 :        761 :         JL_GC_POP();
     717                 :        761 :         return val;
     718                 :            :     }
     719         [ +  + ]:     247801 :     else if (head == jl_using_sym) {
     720                 :       1646 :         jl_sym_t *name = NULL;
     721                 :       1646 :         jl_module_t *from = eval_import_from(m, ex, "using");
     722                 :       1646 :         size_t i = 0;
     723         [ +  + ]:       1646 :         if (from) {
     724                 :        426 :             i = 1;
     725                 :        426 :             ex = (jl_expr_t*)jl_exprarg(ex, 0);
     726                 :            :         }
     727         [ +  + ]:       4744 :         for (; i < jl_expr_nargs(ex); i++) {
     728                 :       3108 :             jl_value_t *a = jl_exprarg(ex, i);
     729   [ +  +  +  + ]:       3108 :             if (jl_is_expr(a) && ((jl_expr_t*)a)->head == jl_dot_sym) {
     730                 :       3104 :                 name = NULL;
     731                 :       3104 :                 jl_module_t *import = eval_import_path(m, from, ((jl_expr_t*)a)->args, &name, "using");
     732                 :       3097 :                 jl_module_t *u = import;
     733         [ +  + ]:       3097 :                 if (name != NULL)
     734                 :       1705 :                     u = (jl_module_t*)jl_eval_global_var(import, name);
     735         [ +  + ]:       3097 :                 if (from) {
     736                 :            :                     // `using A: B` syntax
     737                 :       1378 :                     jl_module_use(m, import, name);
     738                 :            :                 }
     739                 :            :                 else {
     740         [ -  + ]:       1719 :                     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                 :       1719 :                     jl_module_using(m, u);
     745   [ +  +  +  + ]:       1719 :                     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                 :        270 :                         import_module(m, u, NULL);
     749                 :            :                     }
     750                 :            :                 }
     751                 :       3097 :                 continue;
     752                 :            :             }
     753   [ +  +  +  -  :          4 :             else if (from && jl_is_expr(a) && ((jl_expr_t*)a)->head == jl_as_sym && jl_expr_nargs(a) == 2 &&
             +  -  +  - ]
     754   [ +  -  +  - ]:          3 :                      jl_is_expr(jl_exprarg(a, 0)) && ((jl_expr_t*)jl_exprarg(a, 0))->head == jl_dot_sym) {
     755                 :          3 :                 jl_sym_t *asname = (jl_sym_t*)jl_exprarg(a, 1);
     756         [ +  - ]:          3 :                 if (jl_is_symbol(asname)) {
     757                 :          3 :                     jl_expr_t *path = (jl_expr_t*)jl_exprarg(a, 0);
     758                 :          3 :                     name = NULL;
     759                 :          3 :                     jl_module_t *import = eval_import_path(m, from, ((jl_expr_t*)path)->args, &name, "using");
     760         [ -  + ]:          3 :                     assert(name);
     761                 :          3 :                     check_macro_rename(name, asname, "using");
     762                 :            :                     // `using A: B as C` syntax
     763                 :          1 :                     jl_module_use_as(m, import, name, asname);
     764                 :          1 :                     continue;
     765                 :            :                 }
     766                 :            :             }
     767                 :          1 :             jl_eval_errorf(m, "syntax: malformed \"using\" statement");
     768                 :            :         }
     769                 :       1636 :         JL_GC_POP();
     770                 :       1636 :         return jl_nothing;
     771                 :            :     }
     772         [ +  + ]:     246155 :     else if (head == jl_import_sym) {
     773                 :        512 :         jl_sym_t *name = NULL;
     774                 :        512 :         jl_module_t *from = eval_import_from(m, ex, "import");
     775                 :        512 :         size_t i = 0;
     776         [ +  + ]:        512 :         if (from) {
     777                 :        275 :             i = 1;
     778                 :        275 :             ex = (jl_expr_t*)jl_exprarg(ex, 0);
     779                 :            :         }
     780         [ +  + ]:       2496 :         for (; i < jl_expr_nargs(ex); i++) {
     781                 :       1989 :             jl_value_t *a = jl_exprarg(ex, i);
     782   [ +  +  +  + ]:       1989 :             if (jl_is_expr(a) && ((jl_expr_t*)a)->head == jl_dot_sym) {
     783                 :       1974 :                 name = NULL;
     784                 :       1974 :                 jl_module_t *import = eval_import_path(m, from, ((jl_expr_t*)a)->args, &name, "import");
     785         [ +  + ]:       1973 :                 if (name == NULL) {
     786                 :            :                     // `import A` syntax
     787                 :        112 :                     import_module(m, import, NULL);
     788                 :            :                 }
     789                 :            :                 else {
     790                 :            :                     // `import A.B` or `import A: B` syntax
     791                 :       1861 :                     jl_module_import(m, import, name);
     792                 :            :                 }
     793                 :       1973 :                 continue;
     794                 :            :             }
     795   [ +  +  +  -  :         15 :             else if (jl_is_expr(a) && ((jl_expr_t*)a)->head == jl_as_sym && jl_expr_nargs(a) == 2 &&
                   +  - ]
     796   [ +  -  +  - ]:         14 :                      jl_is_expr(jl_exprarg(a, 0)) && ((jl_expr_t*)jl_exprarg(a, 0))->head == jl_dot_sym) {
     797                 :         14 :                 jl_sym_t *asname = (jl_sym_t*)jl_exprarg(a, 1);
     798         [ +  + ]:         14 :                 if (jl_is_symbol(asname)) {
     799                 :         13 :                     jl_expr_t *path = (jl_expr_t*)jl_exprarg(a, 0);
     800                 :         13 :                     name = NULL;
     801                 :         13 :                     jl_module_t *import = eval_import_path(m, from, ((jl_expr_t*)path)->args, &name, "import");
     802         [ -  + ]:         13 :                     if (name == NULL) {
     803                 :            :                         // `import A as B` syntax
     804                 :          0 :                         import_module(m, import, asname);
     805                 :            :                     }
     806                 :            :                     else {
     807                 :         13 :                         check_macro_rename(name, asname, "import");
     808                 :            :                         // `import A.B as C` syntax
     809                 :         11 :                         jl_module_import_as(m, import, name, asname);
     810                 :            :                     }
     811                 :         11 :                     continue;
     812                 :            :                 }
     813                 :            :             }
     814                 :          2 :             jl_eval_errorf(m, "syntax: malformed \"import\" statement");
     815                 :            :         }
     816                 :        507 :         JL_GC_POP();
     817                 :        507 :         return jl_nothing;
     818                 :            :     }
     819         [ +  + ]:     245643 :     else if (head == jl_export_sym) {
     820         [ +  + ]:       6313 :         for (size_t i = 0; i < jl_array_len(ex->args); i++) {
     821                 :       4328 :             jl_sym_t *name = (jl_sym_t*)jl_array_ptr_ref(ex->args, i);
     822         [ -  + ]:       4328 :             if (!jl_is_symbol(name))
     823                 :          0 :                 jl_eval_errorf(m, "syntax: malformed \"export\" statement");
     824                 :       4328 :             jl_module_export(m, name);
     825                 :            :         }
     826                 :       1985 :         JL_GC_POP();
     827                 :       1985 :         return jl_nothing;
     828                 :            :     }
     829         [ +  + ]:     243658 :     else if (head == jl_global_sym) {
     830                 :      28740 :         jl_eval_global_expr(m, ex, 0);
     831                 :      28740 :         JL_GC_POP();
     832                 :      28740 :         return jl_nothing;
     833                 :            :     }
     834         [ +  + ]:     214918 :     else if (head == jl_const_sym) {
     835                 :      31602 :         jl_sym_t *arg = (jl_sym_t*)jl_exprarg(ex, 0);
     836                 :            :         jl_module_t *gm;
     837                 :            :         jl_sym_t *gs;
     838         [ -  + ]:      31602 :         if (jl_is_globalref(arg)) {
     839                 :          0 :             gm = jl_globalref_mod(arg);
     840                 :          0 :             gs = jl_globalref_name(arg);
     841                 :            :         }
     842                 :            :         else {
     843         [ -  + ]:      31602 :             assert(jl_is_symbol(arg));
     844                 :      31602 :             gm = m;
     845                 :      31602 :             gs = (jl_sym_t*)arg;
     846                 :            :         }
     847                 :      31602 :         jl_binding_t *b = jl_get_binding_wr(gm, gs, 1);
     848                 :      31602 :         jl_declare_constant(b);
     849                 :      31601 :         JL_GC_POP();
     850                 :      31601 :         return jl_nothing;
     851                 :            :     }
     852         [ +  + ]:     183316 :     else if (head == jl_toplevel_sym) {
     853                 :      26975 :         jl_value_t *res = jl_nothing;
     854                 :            :         int i;
     855         [ +  + ]:      82614 :         for (i = 0; i < jl_array_len(ex->args); i++) {
     856                 :      55784 :             res = jl_toplevel_eval_flex(m, jl_array_ptr_ref(ex->args, i), fast, 0);
     857                 :            :         }
     858                 :      26830 :         JL_GC_POP();
     859                 :      26830 :         return res;
     860                 :            :     }
     861   [ +  +  +  + ]:     156341 :     else if (head == jl_error_sym || head == jl_incomplete_sym) {
     862         [ -  + ]:         33 :         if (jl_expr_nargs(ex) == 0)
     863                 :          0 :             jl_eval_errorf(m, "malformed \"%s\" expression", jl_symbol_name(head));
     864         [ +  - ]:         33 :         if (jl_is_string(jl_exprarg(ex, 0)))
     865                 :         33 :             jl_eval_errorf(m, "syntax: %s", jl_string_data(jl_exprarg(ex, 0)));
     866                 :          0 :         jl_throw(jl_exprarg(ex, 0));
     867                 :            :     }
     868         [ +  + ]:     156308 :     else if (jl_is_symbol(ex)) {
     869                 :          1 :         JL_GC_POP();
     870                 :          1 :         return jl_eval_global_var(m, (jl_sym_t*)ex);
     871                 :            :     }
     872         [ +  + ]:     156307 :     else if (head == NULL) {
     873                 :         20 :         JL_GC_POP();
     874                 :         20 :         return (jl_value_t*)ex;
     875                 :            :     }
     876                 :            : 
     877                 :     156287 :     int has_intrinsics = 0, has_defs = 0, has_loops = 0, has_opaque = 0, forced_compile = 0;
     878         [ -  + ]:     156287 :     assert(head == jl_thunk_sym);
     879                 :     156287 :     thk = (jl_code_info_t*)jl_exprarg(ex, 0);
     880         [ -  + ]:     156289 :     assert(jl_is_code_info(thk));
     881         [ -  + ]:     156289 :     assert(jl_typeis(thk->code, jl_array_any_type));
     882                 :     156289 :     body_attributes((jl_array_t*)thk->code, &has_intrinsics, &has_defs, &has_loops, &has_opaque, &forced_compile);
     883                 :            : 
     884                 :            :     jl_value_t *result;
     885   [ +  +  +  + ]:     156293 :     if (forced_compile || has_intrinsics ||
     886   [ +  +  +  +  :     156074 :             (!has_defs && fast && has_loops &&
                   +  + ]
     887         [ +  - ]:        904 :             jl_options.compile_enabled != JL_OPTIONS_COMPILE_OFF &&
     888   [ +  +  +  - ]:       1802 :             jl_options.compile_enabled != JL_OPTIONS_COMPILE_MIN &&
     889         [ +  - ]:       1796 :             jl_get_module_compile(m) != JL_OPTIONS_COMPILE_OFF &&
     890                 :        898 :             jl_get_module_compile(m) != JL_OPTIONS_COMPILE_MIN)) {
     891                 :            :         // use codegen
     892                 :       1117 :         mfunc = method_instance_for_thunk(thk, m);
     893                 :       1117 :         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                 :       1117 :         size_t world = jl_atomic_load_acquire(&jl_world_counter);
     899                 :       1117 :         ct->world_age = world;
     900   [ +  +  +  - ]:       1117 :         if (!has_defs && jl_get_module_infer(m) != 0) {
     901                 :       1026 :             (void)jl_type_infer(mfunc, world, 0);
     902                 :            :         }
     903                 :       1117 :         result = jl_invoke(/*func*/NULL, /*args*/NULL, /*nargs*/0, mfunc);
     904                 :       1099 :         ct->world_age = last_age;
     905                 :            :     }
     906                 :            :     else {
     907                 :            :         // use interpreter
     908         [ -  + ]:     155176 :         assert(thk);
     909         [ +  + ]:     155176 :         if (has_opaque) {
     910                 :         18 :             jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0);
     911                 :            :         }
     912                 :     155176 :         result = jl_interpret_toplevel_thunk(m, thk);
     913                 :            :     }
     914                 :            : 
     915                 :     156056 :     JL_GC_POP();
     916                 :     156056 :     return result;
     917                 :            : }
     918                 :            : 
     919                 :     356642 : JL_DLLEXPORT jl_value_t *jl_toplevel_eval(jl_module_t *m, jl_value_t *v)
     920                 :            : {
     921                 :     356642 :     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                 :     152216 : static void jl_check_open_for(jl_module_t *m, const char* funcname)
     926                 :            : {
     927   [ +  +  +  - ]:     152216 :     if (jl_options.incremental && jl_generating_output()) {
     928         [ +  + ]:       2461 :         if (m != jl_main_module) { // TODO: this was grand-fathered in
     929                 :       2375 :             JL_LOCK(&jl_modules_mutex);
     930                 :       2375 :             int open = ptrhash_has(&jl_current_modules, (void*)m);
     931   [ +  +  +  + ]:       2375 :             if (!open && jl_module_init_order != NULL) {
     932                 :          2 :                 size_t i, l = jl_array_len(jl_module_init_order);
     933         [ +  - ]:          4 :                 for (i = 0; i < l; i++) {
     934         [ +  + ]:          4 :                     if (m == (jl_module_t*)jl_array_ptr_ref(jl_module_init_order, i)) {
     935                 :          2 :                         open = 1;
     936                 :          2 :                         break;
     937                 :            :                     }
     938                 :            :                 }
     939                 :            :             }
     940                 :       2375 :             JL_UNLOCK(&jl_modules_mutex);
     941   [ +  +  +  + ]:       2375 :             if (!open && !jl_is__toplevel__mod(m)) {
     942                 :          2 :                 const char* name = jl_symbol_name(m->name);
     943                 :          2 :                 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                 :     152214 : }
     951                 :            : 
     952                 :          4 : JL_DLLEXPORT void jl_check_top_level_effect(jl_module_t *m, char *fname)
     953                 :            : {
     954         [ -  + ]:          4 :     if (jl_current_task->ptls->in_pure_callback)
     955                 :          0 :         jl_errorf("%s cannot be used in a generated function", fname);
     956                 :          4 :     jl_check_open_for(m, fname);
     957                 :          4 : }
     958                 :            : 
     959                 :     151974 : JL_DLLEXPORT jl_value_t *jl_toplevel_eval_in(jl_module_t *m, jl_value_t *ex)
     960                 :            : {
     961                 :     151974 :     jl_task_t *ct = jl_current_task;
     962         [ -  + ]:     151974 :     if (ct->ptls->in_pure_callback)
     963                 :          0 :         jl_error("eval cannot be used in a generated function");
     964                 :     151974 :     jl_check_open_for(m, "eval");
     965                 :     151972 :     jl_value_t *v = NULL;
     966                 :     151972 :     int last_lineno = jl_lineno;
     967                 :     151972 :     const char *last_filename = jl_filename;
     968                 :     151972 :     jl_lineno = 1;
     969                 :     151972 :     jl_filename = "none";
     970   [ +  +  +  + ]:     303689 :     JL_TRY {
     971                 :     151972 :         v = jl_toplevel_eval(m, ex);
     972                 :            :     }
     973         [ +  - ]:        182 :     JL_CATCH {
     974                 :        182 :         jl_lineno = last_lineno;
     975                 :        182 :         jl_filename = last_filename;
     976                 :        182 :         jl_rethrow();
     977                 :            :     }
     978                 :     151717 :     jl_lineno = last_lineno;
     979                 :     151717 :     jl_filename = last_filename;
     980         [ -  + ]:     151717 :     assert(v);
     981                 :     151717 :     return v;
     982                 :            : }
     983                 :            : 
     984                 :         24 : JL_DLLEXPORT jl_value_t *jl_infer_thunk(jl_code_info_t *thk, jl_module_t *m)
     985                 :            : {
     986                 :         24 :     jl_method_instance_t *li = method_instance_for_thunk(thk, m);
     987                 :         24 :     JL_GC_PUSH1(&li);
     988                 :         24 :     jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0);
     989                 :         24 :     jl_task_t *ct = jl_current_task;
     990                 :         24 :     jl_code_info_t *src = jl_type_infer(li, ct->world_age, 0);
     991                 :         24 :     JL_GC_POP();
     992         [ +  - ]:         24 :     if (src)
     993                 :         24 :         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                 :        238 : static jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text,
    1005                 :            :                                      jl_value_t *filename)
    1006                 :            : {
    1007   [ +  -  -  + ]:        238 :     if (!jl_is_string(text) || !jl_is_string(filename)) {
    1008                 :          0 :         jl_errorf("Expected `String`s for `text` and `filename`");
    1009                 :            :     }
    1010                 :        238 :     jl_task_t *ct = jl_current_task;
    1011         [ -  + ]:        238 :     if (ct->ptls->in_pure_callback)
    1012                 :          0 :         jl_error("cannot use include inside a generated function");
    1013                 :        238 :     jl_check_open_for(module, "include");
    1014                 :            : 
    1015                 :        238 :     jl_value_t *result = jl_nothing;
    1016                 :        238 :     jl_value_t *ast = NULL;
    1017                 :        238 :     jl_value_t *expression = NULL;
    1018                 :        238 :     JL_GC_PUSH3(&ast, &result, &expression);
    1019                 :            : 
    1020                 :        238 :     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   [ +  -  -  + ]:        238 :     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                 :        238 :     int last_lineno = jl_lineno;
    1027                 :        238 :     const char *last_filename = jl_filename;
    1028                 :        238 :     size_t last_age = ct->world_age;
    1029                 :        238 :     int lineno = 0;
    1030                 :        238 :     jl_lineno = 0;
    1031                 :        238 :     jl_filename = jl_string_data(filename);
    1032                 :        238 :     int err = 0;
    1033                 :            : 
    1034   [ +  -  +  + ]:        476 :     JL_TRY {
    1035         [ +  + ]:      25106 :         for (size_t i = 0; i < jl_expr_nargs(ast); i++) {
    1036                 :      24868 :             expression = jl_exprarg(ast, i);
    1037         [ +  + ]:      24868 :             if (jl_is_linenode(expression)) {
    1038                 :            :                 // filename is already set above.
    1039                 :      12434 :                 lineno = jl_linenode_line(expression);
    1040                 :      12434 :                 jl_lineno = lineno;
    1041                 :      12434 :                 continue;
    1042                 :            :             }
    1043                 :      12434 :             expression = jl_expand_with_loc_warn(expression, module,
    1044                 :            :                                                  jl_string_data(filename), lineno);
    1045                 :      12434 :             ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
    1046                 :      12434 :             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                 :        238 :     ct->world_age = last_age;
    1056                 :        238 :     jl_lineno = last_lineno;
    1057                 :        238 :     jl_filename = last_filename;
    1058         [ -  + ]:        238 :     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                 :        238 :     JL_GC_POP();
    1066                 :        238 :     return result;
    1067                 :            : }
    1068                 :            : 
    1069                 :            : // Synchronously read content of entire file into a julia String
    1070                 :        238 : static jl_value_t *jl_file_content_as_string(jl_value_t *filename)
    1071                 :            : {
    1072                 :        238 :     const char *fname = jl_string_data(filename);
    1073                 :            :     ios_t f;
    1074         [ -  + ]:        238 :     if (ios_file(&f, fname, 1, 0, 0, 0) == NULL)
    1075                 :          0 :         jl_errorf("File \"%s\" not found", fname);
    1076                 :        238 :     ios_bufmode(&f, bm_none);
    1077                 :        238 :     ios_seek_end(&f);
    1078                 :        238 :     size_t len = ios_pos(&f);
    1079                 :        238 :     jl_value_t *text = jl_alloc_string(len);
    1080                 :        238 :     ios_seek(&f, 0);
    1081         [ -  + ]:        238 :     if (ios_readall(&f, jl_string_data(text), len) != len)
    1082                 :          0 :         jl_errorf("Error reading file \"%s\"", fname);
    1083                 :        238 :     ios_close(&f);
    1084                 :        238 :     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                 :        238 : JL_DLLEXPORT jl_value_t *jl_load_(jl_module_t *module, jl_value_t *filename)
    1090                 :            : {
    1091                 :        238 :     jl_value_t *text = jl_file_content_as_string(filename);
    1092                 :        238 :     JL_GC_PUSH1(&text);
    1093                 :        238 :     jl_value_t *result = jl_parse_eval_all(module, text, filename);
    1094                 :        238 :     JL_GC_POP();
    1095                 :        238 :     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                 :          3 : JL_DLLEXPORT jl_value_t *jl_load(jl_module_t *module, const char *filename)
    1102                 :            : {
    1103                 :          3 :     jl_value_t *filename_ = NULL;
    1104                 :          3 :     JL_GC_PUSH1(&filename_);
    1105                 :          3 :     filename_ = jl_cstr_to_string(filename);
    1106                 :          3 :     jl_value_t *result = jl_load_(module, filename_);
    1107                 :          3 :     JL_GC_POP();
    1108                 :          3 :     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                 :        128 : JL_DLLEXPORT jl_value_t *jl_prepend_cwd(jl_value_t *str)
    1131                 :            : {
    1132                 :        128 :     size_t sz = 1024;
    1133                 :            :     char path[1024];
    1134                 :        128 :     int c = uv_cwd(path, &sz);
    1135         [ -  + ]:        128 :     if (c < 0) {
    1136                 :          0 :         jl_errorf("could not get current directory");
    1137                 :            :     }
    1138                 :        128 :     path[sz] = '/';  // fix later with normpath if Windows
    1139                 :        128 :     const char *fstr = (const char*)jl_string_data(str);
    1140         [ -  + ]:        128 :     if (strlen(fstr) + sz >= 1024) {
    1141                 :          0 :         jl_errorf("use a bigger buffer for jl_fullpath");
    1142                 :            :     }
    1143                 :        128 :     strcpy(path + sz + 1, fstr);
    1144                 :        128 :     return jl_cstr_to_string(path);
    1145                 :            : }
    1146                 :            : 
    1147                 :            : #ifdef __cplusplus
    1148                 :            : }
    1149                 :            : #endif

Generated by: LCOV version 1.14