LCOV - code coverage report
Current view: top level - src - ast.c (source / functions) Hit Total Coverage
Test: [test only] commit 0f242327d2cc9bd130497f44b6350c924185606a Lines: 707 821 86.1 %
Date: 2022-07-16 23:42:53 Functions: 40 50 80.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 293 393 74.6 %

           Branch data     Line data    Source code
       1                 :            : // This file is a part of Julia. License is MIT: https://julialang.org/license
       2                 :            : 
       3                 :            : /*
       4                 :            :   AST
       5                 :            :   components of the front-end, for obtaining and translating syntax trees
       6                 :            : */
       7                 :            : #include <stdlib.h>
       8                 :            : #include <stdio.h>
       9                 :            : #include <string.h>
      10                 :            : #ifdef _OS_WINDOWS_
      11                 :            : #include <malloc.h>
      12                 :            : #endif
      13                 :            : #include "julia.h"
      14                 :            : #include "julia_internal.h"
      15                 :            : #include "flisp.h"
      16                 :            : #include "julia_assert.h"
      17                 :            : 
      18                 :            : #ifdef __cplusplus
      19                 :            : extern "C" {
      20                 :            : #endif
      21                 :            : 
      22                 :            : // head symbols for each expression type
      23                 :            : JL_DLLEXPORT jl_sym_t *jl_call_sym;
      24                 :            : JL_DLLEXPORT jl_sym_t *jl_invoke_sym;
      25                 :            : JL_DLLEXPORT jl_sym_t *jl_invoke_modify_sym;
      26                 :            : JL_DLLEXPORT jl_sym_t *jl_empty_sym;
      27                 :            : JL_DLLEXPORT jl_sym_t *jl_top_sym;
      28                 :            : JL_DLLEXPORT jl_sym_t *jl_module_sym;
      29                 :            : JL_DLLEXPORT jl_sym_t *jl_slot_sym;
      30                 :            : JL_DLLEXPORT jl_sym_t *jl_export_sym;
      31                 :            : JL_DLLEXPORT jl_sym_t *jl_import_sym;
      32                 :            : JL_DLLEXPORT jl_sym_t *jl_toplevel_sym;
      33                 :            : JL_DLLEXPORT jl_sym_t *jl_quote_sym;
      34                 :            : JL_DLLEXPORT jl_sym_t *jl_line_sym;
      35                 :            : JL_DLLEXPORT jl_sym_t *jl_incomplete_sym;
      36                 :            : JL_DLLEXPORT jl_sym_t *jl_goto_sym;
      37                 :            : JL_DLLEXPORT jl_sym_t *jl_goto_ifnot_sym;
      38                 :            : JL_DLLEXPORT jl_sym_t *jl_return_sym;
      39                 :            : JL_DLLEXPORT jl_sym_t *jl_lineinfo_sym;
      40                 :            : JL_DLLEXPORT jl_sym_t *jl_lambda_sym;
      41                 :            : JL_DLLEXPORT jl_sym_t *jl_assign_sym;
      42                 :            : JL_DLLEXPORT jl_sym_t *jl_globalref_sym;
      43                 :            : JL_DLLEXPORT jl_sym_t *jl_do_sym;
      44                 :            : JL_DLLEXPORT jl_sym_t *jl_method_sym;
      45                 :            : JL_DLLEXPORT jl_sym_t *jl_core_sym;
      46                 :            : JL_DLLEXPORT jl_sym_t *jl_enter_sym;
      47                 :            : JL_DLLEXPORT jl_sym_t *jl_leave_sym;
      48                 :            : JL_DLLEXPORT jl_sym_t *jl_pop_exception_sym;
      49                 :            : JL_DLLEXPORT jl_sym_t *jl_exc_sym;
      50                 :            : JL_DLLEXPORT jl_sym_t *jl_error_sym;
      51                 :            : JL_DLLEXPORT jl_sym_t *jl_new_sym;
      52                 :            : JL_DLLEXPORT jl_sym_t *jl_using_sym;
      53                 :            : JL_DLLEXPORT jl_sym_t *jl_splatnew_sym;
      54                 :            : JL_DLLEXPORT jl_sym_t *jl_block_sym;
      55                 :            : JL_DLLEXPORT jl_sym_t *jl_new_opaque_closure_sym;
      56                 :            : JL_DLLEXPORT jl_sym_t *jl_opaque_closure_method_sym;
      57                 :            : JL_DLLEXPORT jl_sym_t *jl_const_sym;
      58                 :            : JL_DLLEXPORT jl_sym_t *jl_thunk_sym;
      59                 :            : JL_DLLEXPORT jl_sym_t *jl_foreigncall_sym;
      60                 :            : JL_DLLEXPORT jl_sym_t *jl_as_sym;
      61                 :            : JL_DLLEXPORT jl_sym_t *jl_global_sym;
      62                 :            : JL_DLLEXPORT jl_sym_t *jl_list_sym;
      63                 :            : JL_DLLEXPORT jl_sym_t *jl_dot_sym;
      64                 :            : JL_DLLEXPORT jl_sym_t *jl_newvar_sym;
      65                 :            : JL_DLLEXPORT jl_sym_t *jl_boundscheck_sym;
      66                 :            : JL_DLLEXPORT jl_sym_t *jl_inbounds_sym;
      67                 :            : JL_DLLEXPORT jl_sym_t *jl_copyast_sym;
      68                 :            : JL_DLLEXPORT jl_sym_t *jl_cfunction_sym;
      69                 :            : JL_DLLEXPORT jl_sym_t *jl_pure_sym;
      70                 :            : JL_DLLEXPORT jl_sym_t *jl_loopinfo_sym;
      71                 :            : JL_DLLEXPORT jl_sym_t *jl_meta_sym;
      72                 :            : JL_DLLEXPORT jl_sym_t *jl_inert_sym;
      73                 :            : JL_DLLEXPORT jl_sym_t *jl_polly_sym;
      74                 :            : JL_DLLEXPORT jl_sym_t *jl_unused_sym;
      75                 :            : JL_DLLEXPORT jl_sym_t *jl_static_parameter_sym;
      76                 :            : JL_DLLEXPORT jl_sym_t *jl_inline_sym;
      77                 :            : JL_DLLEXPORT jl_sym_t *jl_noinline_sym;
      78                 :            : JL_DLLEXPORT jl_sym_t *jl_generated_sym;
      79                 :            : JL_DLLEXPORT jl_sym_t *jl_generated_only_sym;
      80                 :            : JL_DLLEXPORT jl_sym_t *jl_isdefined_sym;
      81                 :            : JL_DLLEXPORT jl_sym_t *jl_propagate_inbounds_sym;
      82                 :            : JL_DLLEXPORT jl_sym_t *jl_specialize_sym;
      83                 :            : JL_DLLEXPORT jl_sym_t *jl_aggressive_constprop_sym;
      84                 :            : JL_DLLEXPORT jl_sym_t *jl_no_constprop_sym;
      85                 :            : JL_DLLEXPORT jl_sym_t *jl_purity_sym;
      86                 :            : JL_DLLEXPORT jl_sym_t *jl_nospecialize_sym;
      87                 :            : JL_DLLEXPORT jl_sym_t *jl_macrocall_sym;
      88                 :            : JL_DLLEXPORT jl_sym_t *jl_colon_sym;
      89                 :            : JL_DLLEXPORT jl_sym_t *jl_hygienicscope_sym;
      90                 :            : JL_DLLEXPORT jl_sym_t *jl_throw_undef_if_not_sym;
      91                 :            : JL_DLLEXPORT jl_sym_t *jl_getfield_undefref_sym;
      92                 :            : JL_DLLEXPORT jl_sym_t *jl_gc_preserve_begin_sym;
      93                 :            : JL_DLLEXPORT jl_sym_t *jl_gc_preserve_end_sym;
      94                 :            : JL_DLLEXPORT jl_sym_t *jl_coverageeffect_sym;
      95                 :            : JL_DLLEXPORT jl_sym_t *jl_escape_sym;
      96                 :            : JL_DLLEXPORT jl_sym_t *jl_aliasscope_sym;
      97                 :            : JL_DLLEXPORT jl_sym_t *jl_popaliasscope_sym;
      98                 :            : JL_DLLEXPORT jl_sym_t *jl_optlevel_sym;
      99                 :            : JL_DLLEXPORT jl_sym_t *jl_thismodule_sym;
     100                 :            : JL_DLLEXPORT jl_sym_t *jl_atom_sym;
     101                 :            : JL_DLLEXPORT jl_sym_t *jl_statement_sym;
     102                 :            : JL_DLLEXPORT jl_sym_t *jl_all_sym;
     103                 :            : JL_DLLEXPORT jl_sym_t *jl_compile_sym;
     104                 :            : JL_DLLEXPORT jl_sym_t *jl_force_compile_sym;
     105                 :            : JL_DLLEXPORT jl_sym_t *jl_infer_sym;
     106                 :            : JL_DLLEXPORT jl_sym_t *jl_max_methods_sym;
     107                 :            : JL_DLLEXPORT jl_sym_t *jl_atomic_sym;
     108                 :            : JL_DLLEXPORT jl_sym_t *jl_not_atomic_sym;
     109                 :            : JL_DLLEXPORT jl_sym_t *jl_unordered_sym;
     110                 :            : JL_DLLEXPORT jl_sym_t *jl_monotonic_sym;
     111                 :            : JL_DLLEXPORT jl_sym_t *jl_acquire_sym;
     112                 :            : JL_DLLEXPORT jl_sym_t *jl_release_sym;
     113                 :            : JL_DLLEXPORT jl_sym_t *jl_acquire_release_sym;
     114                 :            : JL_DLLEXPORT jl_sym_t *jl_sequentially_consistent_sym;
     115                 :            : 
     116                 :            : 
     117                 :            : static const uint8_t flisp_system_image[] = {
     118                 :            : #include <julia_flisp.boot.inc>
     119                 :            : };
     120                 :            : 
     121                 :            : typedef struct _jl_ast_context_t {
     122                 :            :     fl_context_t fl;
     123                 :            :     fltype_t *jvtype;
     124                 :            : 
     125                 :            :     value_t true_sym;
     126                 :            :     value_t false_sym;
     127                 :            :     value_t error_sym;
     128                 :            :     value_t null_sym;
     129                 :            :     value_t ssavalue_sym;
     130                 :            :     value_t slot_sym;
     131                 :            :     jl_module_t *module; // context module for `current-julia-module-counter`
     132                 :            :     struct _jl_ast_context_t *next; // invasive list pointer for getting free contexts
     133                 :            : } jl_ast_context_t;
     134                 :            : 
     135                 :            : static jl_ast_context_t jl_ast_main_ctx;
     136                 :            : 
     137                 :            : #ifdef __clang_gcanalyzer__
     138                 :            : jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT;
     139                 :            : #else
     140                 :            : #define jl_ast_ctx(fl_ctx) container_of(fl_ctx, jl_ast_context_t, fl)
     141                 :            : #endif
     142                 :            : 
     143                 :            : struct macroctx_stack {
     144                 :            :     jl_module_t *m;
     145                 :            :     struct macroctx_stack *parent;
     146                 :            : };
     147                 :            : 
     148                 :            : static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mod);
     149                 :            : static value_t julia_to_scm(fl_context_t *fl_ctx, jl_value_t *v);
     150                 :            : static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, struct macroctx_stack *macroctx, int onelevel, size_t world, int throw_load_error);
     151                 :            : 
     152                 :       6722 : static value_t fl_defined_julia_global(fl_context_t *fl_ctx, value_t *args, uint32_t nargs)
     153                 :            : {
     154                 :            :     // tells whether a var is defined in and *by* the current module
     155                 :       6722 :     argcount(fl_ctx, "defined-julia-global", nargs, 1);
     156                 :       6722 :     (void)tosymbol(fl_ctx, args[0], "defined-julia-global");
     157                 :       6722 :     jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx);
     158                 :       6722 :     jl_sym_t *var = jl_symbol(symbol_name(fl_ctx, args[0]));
     159                 :       6722 :     jl_binding_t *b = jl_get_module_binding(ctx->module, var);
     160   [ +  +  +  + ]:       6722 :     return (b != NULL && b->owner == ctx->module) ? fl_ctx->T : fl_ctx->F;
     161                 :            : }
     162                 :            : 
     163                 :      49143 : static value_t fl_current_module_counter(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT
     164                 :            : {
     165                 :      49143 :     jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx);
     166         [ -  + ]:      49143 :     assert(ctx->module);
     167                 :      49143 :     return fixnum(jl_module_next_counter(ctx->module));
     168                 :            : }
     169                 :            : 
     170                 :          1 : static value_t fl_julia_current_file(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT
     171                 :            : {
     172                 :          1 :     return symbol(fl_ctx, jl_filename);
     173                 :            : }
     174                 :            : 
     175                 :          1 : static value_t fl_julia_current_line(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT
     176                 :            : {
     177                 :          1 :     return fixnum(jl_lineno);
     178                 :            : }
     179                 :            : 
     180                 :          0 : static int jl_is_number(jl_value_t *v)
     181                 :            : {
     182                 :          0 :     jl_datatype_t *t = (jl_datatype_t*)jl_typeof(v);
     183         [ #  # ]:          0 :     for (; t->super != t; t = t->super)
     184         [ #  # ]:          0 :         if (t == jl_number_type)
     185                 :          0 :             return 1;
     186                 :          0 :     return 0;
     187                 :            : }
     188                 :            : 
     189                 :            : // Check whether v is a scalar for purposes of inlining fused-broadcast
     190                 :            : // arguments when lowering; should agree with broadcast.jl on what is a
     191                 :            : // scalar.  When in doubt, return false, since this is only an optimization.
     192                 :          0 : static value_t fl_julia_scalar(fl_context_t *fl_ctx, value_t *args, uint32_t nargs)
     193                 :            : {
     194                 :          0 :     argcount(fl_ctx, "julia-scalar?", nargs, 1);
     195   [ #  #  #  # ]:          0 :     if (fl_isnumber(fl_ctx, args[0]) || fl_isstring(fl_ctx, args[0]))
     196                 :          0 :         return fl_ctx->T;
     197   [ #  #  #  # ]:          0 :     else if (iscvalue(args[0]) && fl_ctx->jl_sym == cv_type((cvalue_t*)ptr(args[0]))) {
     198         [ #  # ]:          0 :         jl_value_t *v = *(jl_value_t**)cptr(args[0]);
     199   [ #  #  #  # ]:          0 :         if (jl_is_number(v) || jl_is_string(v))
     200                 :          0 :             return fl_ctx->T;
     201                 :            :     }
     202                 :          0 :     return fl_ctx->F;
     203                 :            : }
     204                 :            : 
     205                 :            : static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *mod);
     206                 :            : 
     207                 :            : static const builtinspec_t julia_flisp_ast_ext[] = {
     208                 :            :     { "defined-julia-global", fl_defined_julia_global }, // TODO: can we kill this safepoint
     209                 :            :     { "current-julia-module-counter", fl_current_module_counter },
     210                 :            :     { "julia-scalar?", fl_julia_scalar },
     211                 :            :     { "julia-current-file", fl_julia_current_file },
     212                 :            :     { "julia-current-line", fl_julia_current_line },
     213                 :            :     { NULL, NULL }
     214                 :            : };
     215                 :            : 
     216                 :        566 : static void jl_init_ast_ctx(jl_ast_context_t *ctx) JL_NOTSAFEPOINT
     217                 :            : {
     218                 :        566 :     fl_context_t *fl_ctx = &ctx->fl;
     219                 :        566 :     fl_init(fl_ctx, 4*1024*1024);
     220                 :            : 
     221         [ -  + ]:        566 :     if (fl_load_system_image_str(fl_ctx, (char*)flisp_system_image,
     222                 :            :                                  sizeof(flisp_system_image))) {
     223                 :          0 :         jl_error("fatal error loading system image");
     224                 :            :     }
     225                 :            : 
     226                 :        566 :     fl_applyn(fl_ctx, 0, symbol_value(symbol(fl_ctx, "__init_globals")));
     227                 :            : 
     228                 :        566 :     ctx->jvtype = define_opaque_type(fl_ctx->jl_sym, sizeof(void*), NULL, NULL);
     229                 :        566 :     assign_global_builtins(fl_ctx, julia_flisp_ast_ext);
     230                 :        566 :     ctx->true_sym = symbol(fl_ctx, "true");
     231                 :        566 :     ctx->false_sym = symbol(fl_ctx, "false");
     232                 :        566 :     ctx->error_sym = symbol(fl_ctx, "error");
     233                 :        566 :     ctx->null_sym = symbol(fl_ctx, "null");
     234                 :        566 :     ctx->ssavalue_sym = symbol(fl_ctx, "ssavalue");
     235                 :        566 :     ctx->slot_sym = symbol(fl_ctx, "slot");
     236                 :        566 :     ctx->module = NULL;
     237                 :        566 :     set(symbol(fl_ctx, "*scopewarn-opt*"), fixnum(jl_options.warn_scope));
     238                 :        566 : }
     239                 :            : 
     240                 :            : // There should be no GC allocation while holding this lock
     241                 :            : static uv_mutex_t flisp_lock;
     242                 :            : static jl_ast_context_t *jl_ast_ctx_freed = NULL;
     243                 :            : 
     244                 :     257707 : static jl_ast_context_t *jl_ast_ctx_enter(jl_module_t *m) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT
     245                 :            : {
     246                 :     257707 :     JL_SIGATOMIC_BEGIN();
     247                 :     257707 :     uv_mutex_lock(&flisp_lock);
     248                 :     257711 :     jl_ast_context_t *ctx = jl_ast_ctx_freed;
     249         [ +  + ]:     257711 :     if (ctx != NULL) {
     250                 :     257710 :         jl_ast_ctx_freed = ctx->next;
     251                 :     257710 :         ctx->next = NULL;
     252                 :            :     }
     253                 :     257711 :     uv_mutex_unlock(&flisp_lock);
     254         [ +  + ]:     257711 :     if (ctx == NULL) {
     255                 :            :         // Construct a new one if we can't find any
     256                 :          1 :         ctx = (jl_ast_context_t*)calloc(1, sizeof(jl_ast_context_t));
     257                 :          1 :         jl_init_ast_ctx(ctx);
     258                 :            :     }
     259                 :     257711 :     ctx->module = m;
     260                 :     257711 :     return ctx;
     261                 :            : }
     262                 :            : 
     263                 :     258264 : static void jl_ast_ctx_leave(jl_ast_context_t *ctx)
     264                 :            : {
     265                 :     258264 :     uv_mutex_lock(&flisp_lock);
     266                 :     258275 :     ctx->module = NULL;
     267                 :     258275 :     ctx->next = jl_ast_ctx_freed;
     268                 :     258275 :     jl_ast_ctx_freed = ctx;
     269                 :     258275 :     uv_mutex_unlock(&flisp_lock);
     270         [ +  + ]:     258275 :     JL_SIGATOMIC_END();
     271                 :     258275 : }
     272                 :            : 
     273                 :        566 : void jl_init_flisp(void)
     274                 :            : {
     275         [ +  + ]:        566 :     if (jl_ast_ctx_freed)
     276                 :          1 :         return;
     277                 :        565 :     uv_mutex_init(&flisp_lock);
     278                 :        565 :     jl_init_ast_ctx(&jl_ast_main_ctx);
     279                 :            :     // To match the one in jl_ast_ctx_leave
     280                 :        565 :     JL_SIGATOMIC_BEGIN();
     281                 :        565 :     jl_ast_ctx_leave(&jl_ast_main_ctx);
     282                 :            : }
     283                 :            : 
     284                 :        565 : void jl_init_common_symbols(void)
     285                 :            : {
     286                 :        565 :     jl_empty_sym = jl_symbol("");
     287                 :        565 :     jl_call_sym = jl_symbol("call");
     288                 :        565 :     jl_invoke_sym = jl_symbol("invoke");
     289                 :        565 :     jl_invoke_modify_sym = jl_symbol("invoke_modify");
     290                 :        565 :     jl_foreigncall_sym = jl_symbol("foreigncall");
     291                 :        565 :     jl_cfunction_sym = jl_symbol("cfunction");
     292                 :        565 :     jl_quote_sym = jl_symbol("quote");
     293                 :        565 :     jl_inert_sym = jl_symbol("inert");
     294                 :        565 :     jl_top_sym = jl_symbol("top");
     295                 :        565 :     jl_core_sym = jl_symbol("core");
     296                 :        565 :     jl_globalref_sym = jl_symbol("globalref");
     297                 :        565 :     jl_line_sym = jl_symbol("line");
     298                 :        565 :     jl_lineinfo_sym = jl_symbol("lineinfo");
     299                 :        565 :     jl_incomplete_sym = jl_symbol("incomplete");
     300                 :        565 :     jl_error_sym = jl_symbol("error");
     301                 :        565 :     jl_goto_sym = jl_symbol("goto");
     302                 :        565 :     jl_goto_ifnot_sym = jl_symbol("gotoifnot");
     303                 :        565 :     jl_return_sym = jl_symbol("return");
     304                 :        565 :     jl_lambda_sym = jl_symbol("lambda");
     305                 :        565 :     jl_module_sym = jl_symbol("module");
     306                 :        565 :     jl_export_sym = jl_symbol("export");
     307                 :        565 :     jl_import_sym = jl_symbol("import");
     308                 :        565 :     jl_using_sym = jl_symbol("using");
     309                 :        565 :     jl_assign_sym = jl_symbol("=");
     310                 :        565 :     jl_method_sym = jl_symbol("method");
     311                 :        565 :     jl_exc_sym = jl_symbol("the_exception");
     312                 :        565 :     jl_enter_sym = jl_symbol("enter");
     313                 :        565 :     jl_leave_sym = jl_symbol("leave");
     314                 :        565 :     jl_pop_exception_sym = jl_symbol("pop_exception");
     315                 :        565 :     jl_new_sym = jl_symbol("new");
     316                 :        565 :     jl_splatnew_sym = jl_symbol("splatnew");
     317                 :        565 :     jl_new_opaque_closure_sym = jl_symbol("new_opaque_closure");
     318                 :        565 :     jl_opaque_closure_method_sym = jl_symbol("opaque_closure_method");
     319                 :        565 :     jl_const_sym = jl_symbol("const");
     320                 :        565 :     jl_global_sym = jl_symbol("global");
     321                 :        565 :     jl_thunk_sym = jl_symbol("thunk");
     322                 :        565 :     jl_toplevel_sym = jl_symbol("toplevel");
     323                 :        565 :     jl_dot_sym = jl_symbol(".");
     324                 :        565 :     jl_as_sym = jl_symbol("as");
     325                 :        565 :     jl_colon_sym = jl_symbol(":");
     326                 :        565 :     jl_boundscheck_sym = jl_symbol("boundscheck");
     327                 :        565 :     jl_inbounds_sym = jl_symbol("inbounds");
     328                 :        565 :     jl_newvar_sym = jl_symbol("newvar");
     329                 :        565 :     jl_copyast_sym = jl_symbol("copyast");
     330                 :        565 :     jl_loopinfo_sym = jl_symbol("loopinfo");
     331                 :        565 :     jl_pure_sym = jl_symbol("pure");
     332                 :        565 :     jl_meta_sym = jl_symbol("meta");
     333                 :        565 :     jl_list_sym = jl_symbol("list");
     334                 :        565 :     jl_unused_sym = jl_symbol("#unused#");
     335                 :        565 :     jl_slot_sym = jl_symbol("slot");
     336                 :        565 :     jl_static_parameter_sym = jl_symbol("static_parameter");
     337                 :        565 :     jl_inline_sym = jl_symbol("inline");
     338                 :        565 :     jl_noinline_sym = jl_symbol("noinline");
     339                 :        565 :     jl_polly_sym = jl_symbol("polly");
     340                 :        565 :     jl_propagate_inbounds_sym = jl_symbol("propagate_inbounds");
     341                 :        565 :     jl_aggressive_constprop_sym = jl_symbol("aggressive_constprop");
     342                 :        565 :     jl_no_constprop_sym = jl_symbol("no_constprop");
     343                 :        565 :     jl_purity_sym = jl_symbol("purity");
     344                 :        565 :     jl_isdefined_sym = jl_symbol("isdefined");
     345                 :        565 :     jl_nospecialize_sym = jl_symbol("nospecialize");
     346                 :        565 :     jl_specialize_sym = jl_symbol("specialize");
     347                 :        565 :     jl_optlevel_sym = jl_symbol("optlevel");
     348                 :        565 :     jl_compile_sym = jl_symbol("compile");
     349                 :        565 :     jl_force_compile_sym = jl_symbol("force_compile");
     350                 :        565 :     jl_infer_sym = jl_symbol("infer");
     351                 :        565 :     jl_max_methods_sym = jl_symbol("max_methods");
     352                 :        565 :     jl_macrocall_sym = jl_symbol("macrocall");
     353                 :        565 :     jl_escape_sym = jl_symbol("escape");
     354                 :        565 :     jl_hygienicscope_sym = jl_symbol("hygienic-scope");
     355                 :        565 :     jl_gc_preserve_begin_sym = jl_symbol("gc_preserve_begin");
     356                 :        565 :     jl_gc_preserve_end_sym = jl_symbol("gc_preserve_end");
     357                 :        565 :     jl_generated_sym = jl_symbol("generated");
     358                 :        565 :     jl_generated_only_sym = jl_symbol("generated_only");
     359                 :        565 :     jl_throw_undef_if_not_sym = jl_symbol("throw_undef_if_not");
     360                 :        565 :     jl_getfield_undefref_sym = jl_symbol("##getfield##");
     361                 :        565 :     jl_do_sym = jl_symbol("do");
     362                 :        565 :     jl_coverageeffect_sym = jl_symbol("code_coverage_effect");
     363                 :        565 :     jl_aliasscope_sym = jl_symbol("aliasscope");
     364                 :        565 :     jl_popaliasscope_sym = jl_symbol("popaliasscope");
     365                 :        565 :     jl_thismodule_sym = jl_symbol("thismodule");
     366                 :        565 :     jl_block_sym = jl_symbol("block");
     367                 :        565 :     jl_atom_sym = jl_symbol("atom");
     368                 :        565 :     jl_statement_sym = jl_symbol("statement");
     369                 :        565 :     jl_all_sym = jl_symbol("all");
     370                 :        565 :     jl_atomic_sym = jl_symbol("atomic");
     371                 :        565 :     jl_not_atomic_sym = jl_symbol("not_atomic");
     372                 :        565 :     jl_unordered_sym = jl_symbol("unordered");
     373                 :        565 :     jl_monotonic_sym = jl_symbol("monotonic");
     374                 :        565 :     jl_acquire_sym = jl_symbol("acquire");
     375                 :        565 :     jl_release_sym = jl_symbol("release");
     376                 :        565 :     jl_acquire_release_sym = jl_symbol("acquire_release");
     377                 :        565 :     jl_sequentially_consistent_sym = jl_symbol("sequentially_consistent");
     378                 :        565 : }
     379                 :            : 
     380                 :          1 : JL_DLLEXPORT void jl_lisp_prompt(void)
     381                 :            : {
     382                 :            :     // Make `--lisp` sigatomic in order to avoid triggering the sigint safepoint.
     383                 :            :     // We don't have our signal handler registered in that case anyway...
     384                 :          1 :     JL_SIGATOMIC_BEGIN();
     385                 :          1 :     jl_init_flisp();
     386                 :          1 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(jl_main_module);
     387                 :          1 :     fl_context_t *fl_ctx = &ctx->fl;
     388                 :          1 :     fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "__start")), fl_cons(fl_ctx, fl_ctx->NIL,fl_ctx->NIL));
     389                 :          0 :     jl_ast_ctx_leave(ctx);
     390                 :          0 : }
     391                 :            : 
     392                 :          0 : JL_DLLEXPORT void fl_show_profile(void)
     393                 :            : {
     394                 :          0 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
     395                 :          0 :     fl_context_t *fl_ctx = &ctx->fl;
     396                 :          0 :     fl_applyn(fl_ctx, 0, symbol_value(symbol(fl_ctx, "show-profiles")));
     397                 :          0 :     jl_ast_ctx_leave(ctx);
     398                 :          0 : }
     399                 :            : 
     400                 :          0 : JL_DLLEXPORT void fl_clear_profile(void)
     401                 :            : {
     402                 :          0 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
     403                 :          0 :     fl_context_t *fl_ctx = &ctx->fl;
     404                 :          0 :     fl_applyn(fl_ctx, 0, symbol_value(symbol(fl_ctx, "clear-profiles")));
     405                 :          0 :     jl_ast_ctx_leave(ctx);
     406                 :          0 : }
     407                 :            : 
     408                 :          0 : JL_DLLEXPORT void fl_profile(const char *fname)
     409                 :            : {
     410                 :          0 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
     411                 :          0 :     fl_context_t *fl_ctx = &ctx->fl;
     412                 :          0 :     fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "profile-e")), symbol(fl_ctx, fname));
     413                 :          0 :     jl_ast_ctx_leave(ctx);
     414                 :          0 : }
     415                 :            : 
     416                 :            : 
     417                 :   24043600 : static jl_sym_t *scmsym_to_julia(fl_context_t *fl_ctx, value_t s)
     418                 :            : {
     419         [ -  + ]:   24043600 :     assert(issymbol(s));
     420         [ -  + ]:   24043600 :     if (fl_isgensym(fl_ctx, s)) {
     421                 :            :         char gsname[16];
     422                 :          0 :         char *n = uint2str(&gsname[1], sizeof(gsname)-1,
     423                 :          0 :                            ((gensym_t*)ptr(s))->id, 10);
     424                 :          0 :         *(--n) = '#';
     425                 :          0 :         return jl_symbol(n);
     426                 :            :     }
     427                 :   24043500 :     return jl_symbol(symbol_name(fl_ctx, s));
     428                 :            : }
     429                 :            : 
     430                 :     469281 : static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mod)
     431                 :            : {
     432                 :     469281 :     jl_value_t *v = NULL;
     433                 :     469281 :     JL_GC_PUSH1(&v);
     434   [ +  -  +  + ]:     938566 :     JL_TRY {
     435                 :     469283 :         v = scm_to_julia_(fl_ctx, e, mod);
     436                 :            :     }
     437         [ #  # ]:          0 :     JL_CATCH {
     438                 :            :         // if expression cannot be converted, replace with error expr
     439                 :          0 :         jl_expr_t *ex = jl_exprn(jl_error_sym, 1);
     440                 :          0 :         v = (jl_value_t*)ex;
     441                 :          0 :         jl_array_ptr_set(ex->args, 0, jl_cstr_to_string("invalid AST"));
     442                 :            :     }
     443                 :     469283 :     JL_GC_POP();
     444                 :     469283 :     return v;
     445                 :            : }
     446                 :            : 
     447                 :            : extern int64_t conv_to_int64(void *data, numerictype_t tag);
     448                 :            : 
     449                 :   37652900 : static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *mod)
     450                 :            : {
     451         [ +  + ]:   37652900 :     if (fl_isnumber(fl_ctx, e)) {
     452                 :            :         int64_t i64;
     453         [ +  + ]:    8228300 :         if (isfixnum(e)) {
     454                 :    8195970 :             i64 = numval(e);
     455                 :            :         }
     456                 :            :         else {
     457         [ -  + ]:      32331 :             assert(iscprim(e));
     458                 :      32331 :             cprim_t *cp = (cprim_t*)ptr(e);
     459                 :      32331 :             numerictype_t nt = cp_numtype(cp);
     460   [ +  +  +  +  :      32331 :             switch (nt) {
                +  +  + ]
     461                 :      21765 :             case T_DOUBLE:
     462                 :      21765 :                 return (jl_value_t*)jl_box_float64(*(double*)cp_data(cp));
     463                 :        795 :             case T_FLOAT:
     464                 :        795 :                 return (jl_value_t*)jl_box_float32(*(float*)cp_data(cp));
     465                 :       1700 :             case T_UINT8:
     466                 :       1700 :                 return (jl_value_t*)jl_box_uint8(*(uint8_t*)cp_data(cp));
     467                 :        553 :             case T_UINT16:
     468                 :        553 :                 return (jl_value_t*)jl_box_uint16(*(uint16_t*)cp_data(cp));
     469                 :        732 :             case T_UINT32:
     470                 :        732 :                 return (jl_value_t*)jl_box_uint32(*(uint32_t*)cp_data(cp));
     471                 :       6643 :             case T_UINT64:
     472                 :       6643 :                 return (jl_value_t*)jl_box_uint64(*(uint64_t*)cp_data(cp));
     473                 :        143 :             default:
     474                 :            :                 ;
     475                 :            :             }
     476                 :        143 :             i64 = conv_to_int64(cp_data(cp), nt);
     477                 :            :         }
     478                 :            : #ifdef _P64
     479                 :    8196110 :         return (jl_value_t*)jl_box_int64(i64);
     480                 :            : #else
     481                 :            :         if (i64 > (int64_t)S32_MAX || i64 < (int64_t)S32_MIN)
     482                 :            :             return (jl_value_t*)jl_box_int64(i64);
     483                 :            :         else
     484                 :            :             return (jl_value_t*)jl_box_int32((int32_t)i64);
     485                 :            : #endif
     486                 :            :     }
     487         [ +  + ]:   29424600 :     if (issymbol(e))
     488                 :    9387590 :         return (jl_value_t*)scmsym_to_julia(fl_ctx, e);
     489         [ +  + ]:   20037000 :     if (fl_isstring(fl_ctx, e))
     490                 :     146098 :         return jl_pchar_to_string((char*)cvalue_data(e), cvalue_len(e));
     491   [ +  +  -  + ]:   19894300 :     if (iscons(e) || e == fl_ctx->NIL) {
     492                 :            :         value_t hd;
     493                 :            :         jl_sym_t *sym;
     494         [ -  + ]:   18543000 :         if (e == fl_ctx->NIL) {
     495                 :          0 :             hd = e;
     496                 :            :         }
     497                 :            :         else {
     498                 :   18543000 :             hd = car_(e);
     499         [ +  + ]:   18543000 :             if (hd == jl_ast_ctx(fl_ctx)->ssavalue_sym)
     500                 :    2102110 :                 return jl_box_ssavalue(numval(car_(cdr_(e))));
     501         [ +  + ]:   16440900 :             else if (hd == jl_ast_ctx(fl_ctx)->slot_sym)
     502                 :    1477180 :                 return jl_box_slotnumber(numval(car_(cdr_(e))));
     503   [ +  +  +  - ]:   14963700 :             else if (hd == jl_ast_ctx(fl_ctx)->null_sym && llength(e) == 1)
     504                 :      74917 :                 return jl_nothing;
     505   [ +  +  +  - ]:   14888800 :             else if (hd == jl_ast_ctx(fl_ctx)->true_sym && llength(e) == 1)
     506                 :      27601 :                 return jl_true;
     507   [ +  +  +  - ]:   14861200 :             else if (hd == jl_ast_ctx(fl_ctx)->false_sym && llength(e) == 1)
     508                 :     203742 :                 return jl_false;
     509   [ +  +  #  + ]:   14657500 :             else if (hd == fl_ctx->jl_char_sym && llength(e) == 2) {
     510                 :          0 :                 value_t v = car_(cdr_(e));
     511   [ +  #  -  + ]:          0 :                 if (!(iscprim(v) && cp_class((cprim_t*)ptr(v)) == fl_ctx->uint32type))
     512                 :          0 :                     jl_error("malformed julia char");
     513                 :        559 :                 uint32_t c = *(uint32_t*)cp_data((cprim_t*)ptr(v));
     514                 :        559 :                 return jl_box_char(c);
     515                 :            :             }
     516                 :            :         }
     517         [ +  - ]:   14657500 :         if (issymbol(hd))
     518                 :   14657500 :             sym = scmsym_to_julia(fl_ctx, hd);
     519                 :            :         else
     520                 :          0 :             sym = jl_list_sym;
     521                 :   14656800 :         size_t n = llength(e)-1;
     522         [ +  # ]:   14656600 :         if (issymbol(hd))
     523                 :   14656700 :             e = cdr_(e);
     524                 :            :         else
     525                 :          0 :             n++;
     526                 :            :         // nodes with special representations
     527                 :   14656600 :         jl_value_t *ex = NULL, *temp = NULL;
     528   [ +  +  +  -  :   14656600 :         if (sym == jl_line_sym && (n == 1 || n == 2)) {
                   +  # ]
     529                 :     635431 :             jl_value_t *linenum = scm_to_julia_(fl_ctx, car_(e), mod);
     530                 :     634799 :             jl_value_t *file = jl_nothing;
     531                 :     634799 :             JL_GC_PUSH2(&linenum, &file);
     532         [ +  - ]:     634799 :             if (n == 2)
     533                 :     634799 :                 file = scm_to_julia_(fl_ctx, car_(cdr_(e)), mod);
     534                 :     634799 :             temp = jl_new_struct(jl_linenumbernode_type, linenum, file);
     535                 :     634799 :             JL_GC_POP();
     536                 :     634799 :             return temp;
     537                 :            :         }
     538   [ +  +  +  - ]:   14021200 :         else if (sym == jl_lineinfo_sym && n == 5) {
     539                 :     700473 :             jl_value_t *modu=NULL, *name=NULL, *file=NULL, *linenum=NULL, *inlinedat=NULL;
     540                 :     700473 :             JL_GC_PUSH5(&modu, &name, &file, &linenum, &inlinedat);
     541                 :     700473 :             value_t lst = e;
     542                 :     700473 :             modu = scm_to_julia_(fl_ctx, car_(lst), mod);
     543                 :     700472 :             lst = cdr_(lst);
     544                 :     700472 :             name = scm_to_julia_(fl_ctx, car_(lst), mod);
     545                 :     700473 :             lst = cdr_(lst);
     546                 :     700473 :             file = scm_to_julia_(fl_ctx, car_(lst), mod);
     547                 :     700471 :             lst = cdr_(lst);
     548                 :     700471 :             linenum = scm_to_julia_(fl_ctx, car_(lst), mod);
     549                 :     700471 :             lst = cdr_(lst);
     550                 :     700471 :             inlinedat = scm_to_julia_(fl_ctx, car_(lst), mod);
     551                 :     700470 :             temp = jl_new_struct(jl_lineinfonode_type, modu, name, file, linenum, inlinedat);
     552                 :     699122 :             JL_GC_POP();
     553                 :     699122 :             return temp;
     554                 :            :         }
     555                 :   13320700 :         JL_GC_PUSH2(&ex, &temp);
     556         [ +  + ]:   13320700 :         if (sym == jl_goto_sym) {
     557                 :     249696 :             ex = scm_to_julia_(fl_ctx, car_(e), mod);
     558                 :     249696 :             temp = jl_new_struct(jl_gotonode_type, ex);
     559                 :            :         }
     560         [ +  + ]:   13071000 :         else if (sym == jl_goto_ifnot_sym) {
     561                 :     247434 :             ex = scm_to_julia_(fl_ctx, car_(e), mod);
     562                 :     247434 :             temp = scm_to_julia(fl_ctx, car_(cdr_(e)), mod);
     563                 :     247434 :             temp = jl_new_struct(jl_gotoifnot_type, ex, temp);
     564                 :            :         }
     565         [ +  + ]:   12823600 :         else if (sym == jl_newvar_sym) {
     566                 :      72596 :             ex = scm_to_julia_(fl_ctx, car_(e), mod);
     567                 :      72596 :             temp = jl_new_struct(jl_newvarnode_type, ex);
     568                 :            :         }
     569         [ +  + ]:   12751000 :         else if (sym == jl_globalref_sym) {
     570                 :     798246 :             ex = scm_to_julia_(fl_ctx, car_(e), mod);
     571                 :     798246 :             temp = scm_to_julia_(fl_ctx, car_(cdr_(e)), mod);
     572         [ -  + ]:     798246 :             assert(jl_is_module(ex));
     573         [ -  + ]:     798246 :             assert(jl_is_symbol(temp));
     574                 :     798246 :             temp = jl_module_globalref((jl_module_t*)ex, (jl_sym_t*)temp);
     575                 :            :         }
     576         [ +  + ]:   11952800 :         else if (sym == jl_top_sym) {
     577         [ -  + ]:     355113 :             assert(mod && "top should not be generated by the parser");
     578                 :     355113 :             ex = scm_to_julia_(fl_ctx, car_(e), mod);
     579         [ -  + ]:     355114 :             assert(jl_is_symbol(ex));
     580                 :     355114 :             temp = jl_module_globalref(jl_base_relative_to(mod), (jl_sym_t*)ex);
     581                 :            :         }
     582         [ +  + ]:   11597700 :         else if (sym == jl_core_sym) {
     583                 :    1411100 :             ex = scm_to_julia_(fl_ctx, car_(e), mod);
     584         [ -  + ]:    1411100 :             assert(jl_is_symbol(ex));
     585                 :    1411100 :             temp = jl_module_globalref(jl_core_module, (jl_sym_t*)ex);
     586                 :            :         }
     587         [ +  + ]:   10186600 :         else if (sym == jl_thismodule_sym) {
     588                 :     749083 :             temp = (jl_value_t*)mod;
     589                 :            :         }
     590   [ +  +  +  +  :    9437480 :         else if (iscons(e) && (sym == jl_inert_sym || (sym == jl_quote_sym && (!iscons(car_(e)))))) {
             +  +  +  + ]
     591                 :    1100370 :             ex = scm_to_julia_(fl_ctx, car_(e), mod);
     592                 :    1102070 :             temp = jl_new_struct(jl_quotenode_type, ex);
     593                 :            :         }
     594         [ +  + ]:   13322500 :         if (temp) {
     595                 :    4985290 :             JL_GC_POP();
     596                 :    4985290 :             return temp;
     597                 :            :         }
     598                 :    8337200 :         ex = (jl_value_t*)jl_exprn(sym, n);
     599                 :            :         size_t i;
     600         [ +  + ]:   35718400 :         for (i = 0; i < n; i++) {
     601         [ -  + ]:   27379800 :             assert(iscons(e));
     602                 :   27379800 :             jl_array_ptr_set(((jl_expr_t*)ex)->args, i, scm_to_julia_(fl_ctx, car_(e), mod));
     603                 :   27381400 :             e = cdr_(e);
     604                 :            :         }
     605         [ +  + ]:    8338570 :         if (sym == jl_lambda_sym)
     606                 :     232371 :             ex = (jl_value_t*)jl_new_code_info_from_ir((jl_expr_t*)ex);
     607                 :    8338570 :         JL_GC_POP();
     608         [ +  + ]:    8338570 :         if (sym == jl_list_sym)
     609                 :    2204670 :             return (jl_value_t*)((jl_expr_t*)ex)->args;
     610                 :    6133900 :         return (jl_value_t*)ex;
     611                 :            :     }
     612   [ +  +  +  - ]:    1351310 :     if (iscprim(e) && cp_class((cprim_t*)ptr(e)) == fl_ctx->wchartype) {
     613                 :       4269 :         uint32_t c, u = *(uint32_t*)cp_data((cprim_t*)ptr(e));
     614         [ +  + ]:       4269 :         if (u < 0x80) {
     615                 :       3990 :             c = u << 24;
     616                 :            :         } else {
     617                 :        279 :             c = ((u << 0) & 0x0000003f) | ((u << 2) & 0x00003f00) |
     618                 :        279 :                 ((u << 4) & 0x003f0000) | ((u << 6) & 0x3f000000);
     619         [ +  + ]:        442 :             c = u < 0x00000800 ? (c << 16) | 0xc0800000 :
     620         [ +  + ]:        163 :                 u < 0x00010000 ? (c <<  8) | 0xe0808000 :
     621                 :            :                                  (c <<  0) | 0xf0808080 ;
     622                 :            :         }
     623                 :       4269 :         return jl_box_char(c);
     624                 :            :     }
     625   [ +  -  +  - ]:    1347040 :     if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jl_ast_ctx(fl_ctx)->jvtype) {
     626                 :    1347040 :         return *(jl_value_t**)cv_data((cvalue_t*)ptr(e));
     627                 :            :     }
     628                 :          0 :     jl_error("malformed tree");
     629                 :            : }
     630                 :            : 
     631                 :            : static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v, int check_valid);
     632                 :            : 
     633                 :     136854 : static value_t julia_to_scm(fl_context_t *fl_ctx, jl_value_t *v)
     634                 :            : {
     635                 :            :     value_t temp;
     636                 :            :     // need try/catch to reset GC handle stack in case of error
     637   [ +  +  +  + ]:     273702 :     FL_TRY_EXTERN(fl_ctx) {
     638                 :     136854 :         temp = julia_to_scm_(fl_ctx, v, 1);
     639                 :            :     }
     640         [ +  + ]:         10 :     FL_CATCH_EXTERN(fl_ctx) {
     641                 :          5 :         temp = fl_ctx->lasterror;
     642                 :            :     }
     643                 :     136853 :     return temp;
     644                 :            : }
     645                 :            : 
     646                 :    4271450 : static void array_to_list(fl_context_t *fl_ctx, jl_array_t *a, value_t *pv, int check_valid)
     647                 :            : {
     648                 :            :     value_t temp;
     649         [ +  + ]:   15547500 :     for(long i=jl_array_len(a)-1; i >= 0; i--) {
     650                 :   11276100 :         *pv = fl_cons(fl_ctx, fl_ctx->NIL, *pv);
     651                 :   11276100 :         temp = julia_to_scm_(fl_ctx, jl_array_ptr_ref(a,i), check_valid);
     652                 :            :         // note: must be separate statement
     653                 :   11276100 :         car_(*pv) = temp;
     654                 :            :     }
     655                 :    4271440 : }
     656                 :            : 
     657                 :     730045 : static value_t julia_to_list2(fl_context_t *fl_ctx, jl_value_t *a, jl_value_t *b, int check_valid)
     658                 :            : {
     659                 :     730045 :     value_t sa = julia_to_scm_(fl_ctx, a, check_valid);
     660                 :     730045 :     fl_gc_handle(fl_ctx, &sa);
     661                 :     730045 :     value_t sb = julia_to_scm_(fl_ctx, b, check_valid);
     662                 :     730045 :     value_t l = fl_list2(fl_ctx, sa, sb);
     663                 :     730045 :     fl_free_gc_handles(fl_ctx, 1);
     664                 :     730045 :     return l;
     665                 :            : }
     666                 :            : 
     667                 :   19786600 : static int julia_to_scm_noalloc1(fl_context_t *fl_ctx, jl_value_t *v, value_t *retval) JL_NOTSAFEPOINT
     668                 :            : {
     669         [ +  + ]:   19786600 :     if (v == NULL)
     670                 :          2 :         lerror(fl_ctx, symbol(fl_ctx, "error"), "undefined reference in AST");
     671         [ +  + ]:   19786600 :     else if (jl_is_symbol(v))
     672                 :   11086500 :         *retval = symbol(fl_ctx, jl_symbol_name((jl_sym_t*)v));
     673         [ +  + ]:    8700130 :     else if (v == jl_true)
     674                 :      21640 :         *retval = fl_cons(fl_ctx, jl_ast_ctx(fl_ctx)->true_sym, fl_ctx->NIL);
     675         [ +  + ]:    8678490 :     else if (v == jl_false)
     676                 :     142973 :         *retval = fl_cons(fl_ctx, jl_ast_ctx(fl_ctx)->false_sym, fl_ctx->NIL);
     677         [ +  + ]:    8535520 :     else if (v == jl_nothing)
     678                 :       5986 :         *retval = fl_cons(fl_ctx, jl_ast_ctx(fl_ctx)->null_sym, fl_ctx->NIL);
     679                 :            :     else
     680                 :    8529530 :         return 0;
     681                 :   11257100 :     return 1;
     682                 :            : }
     683                 :            : 
     684                 :    2654560 : static value_t julia_to_scm_noalloc2(fl_context_t *fl_ctx, jl_value_t *v, int check_valid) JL_NOTSAFEPOINT
     685                 :            : {
     686   [ +  +  +  +  :    2654560 :     if (jl_is_long(v) && fits_fixnum(jl_unbox_long(v)))
                   +  + ]
     687                 :    1995800 :         return fixnum(jl_unbox_long(v));
     688         [ +  + ]:     658759 :     if (check_valid) {
     689         [ +  + ]:     633379 :         if (jl_is_ssavalue(v))
     690                 :          1 :             lerror(fl_ctx, symbol(fl_ctx, "error"), "SSAValue objects should not occur in an AST");
     691   [ +  +  -  + ]:     633378 :         if (jl_is_slot(v))
     692                 :          1 :             lerror(fl_ctx, symbol(fl_ctx, "error"), "Slot objects should not occur in an AST");
     693                 :            :     }
     694                 :     658757 :     value_t opaque = cvalue(fl_ctx, jl_ast_ctx(fl_ctx)->jvtype, sizeof(void*));
     695                 :     658757 :     *(jl_value_t**)cv_data((cvalue_t*)ptr(opaque)) = v;
     696                 :     658757 :     return opaque;
     697                 :            : }
     698                 :            : 
     699                 :    1759010 : static value_t julia_to_scm_noalloc(fl_context_t *fl_ctx, jl_value_t *v, int check_valid) JL_NOTSAFEPOINT
     700                 :            : {
     701                 :            :     value_t retval;
     702         [ +  + ]:    1759010 :     if (julia_to_scm_noalloc1(fl_ctx, v, &retval))
     703                 :     879506 :         return retval;
     704   [ +  -  +  -  :     879506 :     assert(!jl_is_expr(v) &&
          +  -  +  -  +  
                -  +  - ]
     705                 :            :            !jl_typeis(v, jl_linenumbernode_type) &&
     706                 :            :            !jl_typeis(v, jl_gotonode_type) &&
     707                 :            :            !jl_typeis(v, jl_quotenode_type) &&
     708                 :            :            !jl_typeis(v, jl_newvarnode_type) &&
     709                 :            :            !jl_typeis(v, jl_globalref_type));
     710                 :     879506 :     return julia_to_scm_noalloc2(fl_ctx, v, check_valid);
     711                 :            : }
     712                 :            : 
     713                 :     879506 : static value_t julia_to_list2_noalloc(fl_context_t *fl_ctx, jl_value_t *a, jl_value_t *b, int check_valid) JL_NOTSAFEPOINT
     714                 :            : {
     715                 :     879506 :     value_t sa = julia_to_scm_noalloc(fl_ctx, a, check_valid);
     716                 :     879506 :     fl_gc_handle(fl_ctx, &sa);
     717                 :     879506 :     value_t sb = julia_to_scm_noalloc(fl_ctx, b, check_valid);
     718                 :     879506 :     value_t l = fl_list2(fl_ctx, sa, sb);
     719                 :     879506 :     fl_free_gc_handles(fl_ctx, 1);
     720                 :     879506 :     return l;
     721                 :            : }
     722                 :            : 
     723                 :   18027600 : static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v, int check_valid)
     724                 :            : {
     725                 :            :     value_t retval;
     726         [ +  + ]:   18027600 :     if (julia_to_scm_noalloc1(fl_ctx, v, &retval))
     727                 :   10377600 :         return retval;
     728         [ +  + ]:    7650020 :     if (jl_is_expr(v)) {
     729                 :    4265430 :         jl_expr_t *ex = (jl_expr_t*)v;
     730                 :    4265430 :         value_t args = fl_ctx->NIL;
     731                 :    4265430 :         fl_gc_handle(fl_ctx, &args);
     732   [ +  +  +  + ]:    4265430 :         if (jl_expr_nargs(ex) > 520000 && ex->head != jl_block_sym)
     733                 :          1 :             lerror(fl_ctx, symbol(fl_ctx, "error"), "expression too large");
     734                 :    4265430 :         array_to_list(fl_ctx, ex->args, &args, check_valid);
     735                 :    4265430 :         value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)ex->head, check_valid);
     736   [ +  +  +  -  :    4265430 :         if (ex->head == jl_lambda_sym && jl_expr_nargs(ex)>0 && jl_is_array(jl_exprarg(ex,0))) {
                   +  - ]
     737                 :       6014 :             value_t llist = fl_ctx->NIL;
     738                 :       6014 :             fl_gc_handle(fl_ctx, &llist);
     739                 :       6014 :             array_to_list(fl_ctx, (jl_array_t*)jl_exprarg(ex,0), &llist, check_valid);
     740                 :       6014 :             car_(args) = llist;
     741                 :       6014 :             fl_free_gc_handles(fl_ctx, 1);
     742                 :            :         }
     743                 :    4265430 :         value_t scmv = fl_cons(fl_ctx, hd, args);
     744                 :    4265430 :         fl_free_gc_handles(fl_ctx, 1);
     745                 :    4265430 :         return scmv;
     746                 :            :     }
     747                 :            :     // GC Note: jl_fieldref(v, 0) allocates for GotoNode
     748                 :            :     //          but we don't need a GC root here because julia_to_list2_noalloc
     749                 :            :     //          shouldn't allocate in this case.
     750         [ +  + ]:    3384580 :     if (jl_typeis(v, jl_linenumbernode_type)) {
     751                 :     879506 :         jl_value_t *file = jl_fieldref_noalloc(v,1);
     752                 :     879506 :         jl_value_t *line = jl_fieldref(v,0);
     753                 :     879506 :         value_t args = julia_to_list2_noalloc(fl_ctx, line, file, check_valid);
     754                 :     879506 :         fl_gc_handle(fl_ctx, &args);
     755                 :     879506 :         value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)jl_line_sym, check_valid);
     756                 :     879506 :         value_t scmv = fl_cons(fl_ctx, hd, args);
     757                 :     879506 :         fl_free_gc_handles(fl_ctx, 1);
     758                 :     879506 :         return scmv;
     759                 :            :     }
     760         [ -  + ]:    2505080 :     if (jl_typeis(v, jl_gotonode_type))
     761                 :          0 :         return julia_to_list2_noalloc(fl_ctx, (jl_value_t*)jl_goto_sym, jl_fieldref(v,0), check_valid);
     762         [ +  + ]:    2505080 :     if (jl_typeis(v, jl_quotenode_type))
     763                 :     701725 :         return julia_to_list2(fl_ctx, (jl_value_t*)jl_inert_sym, jl_fieldref_noalloc(v,0), 0);
     764         [ -  + ]:    1803350 :     if (jl_typeis(v, jl_newvarnode_type))
     765                 :          0 :         return julia_to_list2_noalloc(fl_ctx, (jl_value_t*)jl_newvar_sym, jl_fieldref(v,0), check_valid);
     766         [ +  + ]:    1803350 :     if (jl_typeis(v, jl_globalref_type)) {
     767                 :      28320 :         jl_module_t *m = jl_globalref_mod(v);
     768                 :      28320 :         jl_sym_t *sym = jl_globalref_name(v);
     769         [ +  + ]:      28320 :         if (m == jl_core_module)
     770                 :      18707 :             return julia_to_list2(fl_ctx, (jl_value_t*)jl_core_sym,
     771                 :            :                                   (jl_value_t*)sym, check_valid);
     772                 :       9613 :         value_t args = julia_to_list2(fl_ctx, (jl_value_t*)m, (jl_value_t*)sym, check_valid);
     773                 :       9613 :         fl_gc_handle(fl_ctx, &args);
     774                 :       9613 :         value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)jl_globalref_sym, check_valid);
     775                 :       9613 :         value_t scmv = fl_cons(fl_ctx, hd, args);
     776                 :       9613 :         fl_free_gc_handles(fl_ctx, 1);
     777                 :       9613 :         return scmv;
     778                 :            :     }
     779                 :    1775030 :     return julia_to_scm_noalloc2(fl_ctx, v, check_valid);
     780                 :            : }
     781                 :            : 
     782                 :            : // Parse `text` starting at 0-based `offset` and attributing the content to
     783                 :            : // `filename`. Return an svec of (parsed_expr, final_offset)
     784                 :      85017 : JL_DLLEXPORT jl_value_t *jl_fl_parse(const char *text, size_t text_len,
     785                 :            :                                      jl_value_t *filename, size_t lineno,
     786                 :            :                                      size_t offset, jl_value_t *options)
     787                 :            : {
     788                 :            :     JL_TIMING(PARSING);
     789         [ -  + ]:      85017 :     if (offset > text_len) {
     790                 :          0 :         jl_value_t *textstr = jl_pchar_to_string(text, text_len);
     791                 :          0 :         JL_GC_PUSH1(&textstr);
     792                 :          0 :         jl_bounds_error(textstr, jl_box_long(offset+1));
     793                 :            :     }
     794                 :      85017 :     jl_sym_t *rule = (jl_sym_t*)options;
     795   [ +  +  +  +  :      85017 :     if (rule != jl_atom_sym && rule != jl_statement_sym && rule != jl_all_sym) {
                   -  + ]
     796                 :          0 :         jl_error("jl_fl_parse: unrecognized parse options");
     797                 :            :     }
     798   [ +  +  -  + ]:      85017 :     if (offset != 0 && rule == jl_all_sym) {
     799                 :          0 :         jl_error("Parse `all`: offset not supported");
     800                 :            :     }
     801                 :            : 
     802                 :      85017 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
     803                 :      85017 :     fl_context_t *fl_ctx = &ctx->fl;
     804                 :      85017 :     value_t fl_text = cvalue_static_cstrn(fl_ctx, text, text_len);
     805                 :      85017 :     fl_gc_handle(fl_ctx, &fl_text);
     806                 :      85017 :     value_t fl_filename = cvalue_static_cstrn(fl_ctx, jl_string_data(filename),
     807                 :            :                                               jl_string_len(filename));
     808                 :      85017 :     fl_gc_handle(fl_ctx, &fl_filename);
     809                 :            :     value_t fl_expr;
     810                 :      85017 :     size_t offset1 = 0;
     811         [ +  + ]:      85017 :     if (rule == jl_all_sym) {
     812                 :       1872 :         value_t e = fl_applyn(fl_ctx, 3, symbol_value(symbol(fl_ctx, "jl-parse-all")),
     813                 :            :                               fl_text, fl_filename, fixnum(lineno));
     814                 :       1872 :         fl_expr = e;
     815         [ -  + ]:       1872 :         offset1 = e == fl_ctx->FL_EOF ? text_len : 0;
     816                 :            :     }
     817                 :            :     else {
     818         [ +  + ]:      83145 :         value_t greedy = rule == jl_statement_sym ? fl_ctx->T : fl_ctx->F;
     819                 :      83145 :         value_t p = fl_applyn(fl_ctx, 5, symbol_value(symbol(fl_ctx, "jl-parse-one")),
     820                 :            :                               fl_text, fl_filename, fixnum(offset), greedy, fixnum(lineno));
     821                 :      83145 :         fl_expr = car_(p);
     822                 :      83145 :         offset1 = tosize(fl_ctx, cdr_(p), "parse");
     823                 :            :     }
     824                 :      85017 :     fl_free_gc_handles(fl_ctx, 2);
     825                 :            : 
     826                 :            :     // Convert to julia values
     827                 :      85017 :     jl_value_t *expr = NULL, *end_offset = NULL;
     828                 :      85017 :     JL_GC_PUSH2(&expr, &end_offset);
     829         [ +  + ]:      85017 :     expr = fl_expr == fl_ctx->FL_EOF ? jl_nothing : scm_to_julia(fl_ctx, fl_expr, NULL);
     830                 :      85017 :     end_offset = jl_box_long(offset1);
     831                 :      85017 :     jl_ast_ctx_leave(ctx);
     832                 :      85017 :     jl_value_t *result = (jl_value_t*)jl_svec2(expr, end_offset);
     833                 :      85017 :     JL_GC_POP();
     834                 :      85017 :     return result;
     835                 :            : }
     836                 :            : 
     837                 :            : // returns either an expression or a thunk
     838                 :      13471 : jl_value_t *jl_call_scm_on_ast(const char *funcname, jl_value_t *expr, jl_module_t *inmodule)
     839                 :            : {
     840                 :      13471 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
     841                 :      13471 :     fl_context_t *fl_ctx = &ctx->fl;
     842                 :      13471 :     value_t arg = julia_to_scm(fl_ctx, expr);
     843                 :      13471 :     value_t e = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, funcname)), arg);
     844                 :      13471 :     jl_value_t *result = scm_to_julia(fl_ctx, e, inmodule);
     845                 :      13471 :     JL_GC_PUSH1(&result);
     846                 :      13471 :     jl_ast_ctx_leave(ctx);
     847                 :      13471 :     JL_GC_POP();
     848                 :      13471 :     return result;
     849                 :            : }
     850                 :            : 
     851                 :      37636 : static jl_value_t *jl_call_scm_on_ast_and_loc(const char *funcname, jl_value_t *expr,
     852                 :            :                                               jl_module_t *inmodule, const char *file, int line)
     853                 :            : {
     854                 :      37636 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
     855                 :      37636 :     fl_context_t *fl_ctx = &ctx->fl;
     856                 :      37636 :     value_t arg = julia_to_scm(fl_ctx, expr);
     857                 :      37636 :     value_t e = fl_applyn(fl_ctx, 3, symbol_value(symbol(fl_ctx, funcname)), arg,
     858                 :      37636 :                           symbol(fl_ctx, file), fixnum(line));
     859                 :      37636 :     jl_value_t *result = scm_to_julia(fl_ctx, e, inmodule);
     860                 :      37636 :     JL_GC_PUSH1(&result);
     861                 :      37636 :     jl_ast_ctx_leave(ctx);
     862                 :      37636 :     JL_GC_POP();
     863                 :      37636 :     return result;
     864                 :            : }
     865                 :            : 
     866                 :            : // syntax tree accessors
     867                 :            : 
     868                 :   14450100 : JL_DLLEXPORT jl_value_t *jl_copy_ast(jl_value_t *expr)
     869                 :            : {
     870         [ +  + ]:   14450100 :     if (!expr)
     871                 :          2 :         return NULL;
     872         [ +  + ]:   14450100 :     if (jl_is_code_info(expr)) {
     873                 :         12 :         jl_code_info_t *new_ci = (jl_code_info_t *)expr;
     874                 :         12 :         jl_array_t *new_code = NULL;
     875                 :         12 :         JL_GC_PUSH2(&new_ci, &new_code);
     876                 :         12 :         new_ci = jl_copy_code_info(new_ci);
     877                 :         12 :         new_code = jl_array_copy(new_ci->code);
     878                 :         12 :         size_t clen = jl_array_len(new_code);
     879         [ +  + ]:         46 :         for (int i = 0; i < clen; ++i) {
     880                 :         34 :             jl_array_ptr_set(new_code, i, jl_copy_ast(
     881                 :            :                 jl_array_ptr_ref(new_code, i)
     882                 :            :             ));
     883                 :            :         }
     884                 :         12 :         new_ci->code = new_code;
     885                 :         12 :         jl_gc_wb(new_ci, new_code);
     886                 :         12 :         new_ci->slotnames = jl_array_copy(new_ci->slotnames);
     887                 :         12 :         jl_gc_wb(new_ci, new_ci->slotnames);
     888                 :         12 :         new_ci->slotflags = jl_array_copy(new_ci->slotflags);
     889                 :         12 :         jl_gc_wb(new_ci, new_ci->slotflags);
     890                 :         12 :         new_ci->codelocs = (jl_value_t*)jl_array_copy((jl_array_t*)new_ci->codelocs);
     891                 :         12 :         jl_gc_wb(new_ci, new_ci->codelocs);
     892                 :         12 :         new_ci->linetable = (jl_value_t*)jl_array_copy((jl_array_t*)new_ci->linetable);
     893                 :         12 :         jl_gc_wb(new_ci, new_ci->linetable);
     894                 :         12 :         new_ci->ssaflags = jl_array_copy(new_ci->ssaflags);
     895                 :         12 :         jl_gc_wb(new_ci, new_ci->ssaflags);
     896                 :            : 
     897         [ -  + ]:         12 :         if (new_ci->edges != jl_nothing) {
     898                 :          0 :             new_ci->edges = (jl_value_t*)jl_array_copy((jl_array_t*)new_ci->edges);
     899                 :          0 :             jl_gc_wb(new_ci, new_ci->edges);
     900                 :            :         }
     901                 :            : 
     902         [ -  + ]:         12 :         if (jl_is_array(new_ci->ssavaluetypes)) {
     903                 :          0 :             new_ci->ssavaluetypes = (jl_value_t*)jl_array_copy((jl_array_t*)new_ci->ssavaluetypes);
     904                 :          0 :             jl_gc_wb(new_ci, new_ci->ssavaluetypes);
     905                 :            :         }
     906                 :         12 :         JL_GC_POP();
     907                 :         12 :         return (jl_value_t*)new_ci;
     908                 :            :     }
     909         [ +  + ]:   14450000 :     if (jl_is_expr(expr)) {
     910                 :    5187120 :         jl_expr_t *e = (jl_expr_t*)expr;
     911                 :    5187120 :         size_t i, l = jl_array_len(e->args);
     912                 :    5187120 :         jl_expr_t *ne = jl_exprn(e->head, l);
     913                 :    5187120 :         JL_GC_PUSH2(&ne, &expr);
     914         [ +  + ]:   19130400 :         for (i = 0; i < l; i++) {
     915                 :   13943200 :             jl_value_t *a = jl_exprarg(e, i);
     916                 :   13943200 :             jl_exprargset(ne, i, jl_copy_ast(a));
     917                 :            :         }
     918                 :    5187120 :         JL_GC_POP();
     919                 :    5187120 :         return (jl_value_t*)ne;
     920                 :            :     }
     921         [ +  + ]:    9262920 :     if (jl_is_phinode(expr)) {
     922                 :          2 :         jl_array_t *edges = (jl_array_t*)jl_fieldref_noalloc(expr, 0);
     923                 :          2 :         jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(expr, 1);
     924                 :          2 :         JL_GC_PUSH2(&edges, &values);
     925                 :          2 :         edges = jl_array_copy(edges);
     926                 :          2 :         values = jl_array_copy(values);
     927                 :          2 :         jl_value_t *ret = jl_new_struct(jl_phinode_type, edges, values);
     928                 :          2 :         JL_GC_POP();
     929                 :          2 :         return ret;
     930                 :            :     }
     931         [ -  + ]:    9262920 :     if (jl_is_phicnode(expr)) {
     932                 :          0 :         jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(expr, 0);
     933                 :          0 :         JL_GC_PUSH1(&values);
     934                 :          0 :         values = jl_array_copy(values);
     935                 :          0 :         jl_value_t *ret = jl_new_struct(jl_phinode_type, values);
     936                 :          0 :         JL_GC_POP();
     937                 :          0 :         return ret;
     938                 :            :     }
     939                 :    9262920 :     return expr;
     940                 :            : }
     941                 :            : 
     942                 :       9426 : JL_DLLEXPORT int jl_is_operator(char *sym)
     943                 :            : {
     944                 :       9426 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
     945                 :       9426 :     fl_context_t *fl_ctx = &ctx->fl;
     946                 :       9426 :     int res = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "operator?")), symbol(fl_ctx, sym)) == fl_ctx->T;
     947                 :       9426 :     jl_ast_ctx_leave(ctx);
     948                 :       9426 :     return res;
     949                 :            : }
     950                 :            : 
     951                 :          3 : JL_DLLEXPORT int jl_is_unary_operator(char *sym)
     952                 :            : {
     953                 :          3 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
     954                 :          3 :     fl_context_t *fl_ctx = &ctx->fl;
     955                 :          3 :     int res = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "unary-op?")), symbol(fl_ctx, sym)) == fl_ctx->T;
     956                 :          3 :     jl_ast_ctx_leave(ctx);
     957                 :          3 :     return res;
     958                 :            : }
     959                 :            : 
     960                 :          0 : JL_DLLEXPORT int jl_is_unary_and_binary_operator(char *sym)
     961                 :            : {
     962                 :          0 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
     963                 :          0 :     fl_context_t *fl_ctx = &ctx->fl;
     964                 :          0 :     int res = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "unary-and-binary-op?")), symbol(fl_ctx, sym)) == fl_ctx->T;
     965                 :          0 :     jl_ast_ctx_leave(ctx);
     966                 :          0 :     return res;
     967                 :            : }
     968                 :            : 
     969                 :       1226 : JL_DLLEXPORT int jl_is_syntactic_operator(char *sym)
     970                 :            : {
     971                 :       1226 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
     972                 :       1226 :     fl_context_t *fl_ctx = &ctx->fl;
     973                 :       1226 :     int res = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "syntactic-op?")), symbol(fl_ctx, sym)) == fl_ctx->T;
     974                 :       1226 :     jl_ast_ctx_leave(ctx);
     975                 :       1226 :     return res;
     976                 :            : }
     977                 :            : 
     978                 :      25184 : JL_DLLEXPORT int jl_operator_precedence(char *sym)
     979                 :            : {
     980                 :      25184 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
     981                 :      25184 :     fl_context_t *fl_ctx = &ctx->fl;
     982                 :      25184 :     int res = numval(fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "operator-precedence")), symbol(fl_ctx, sym)));
     983                 :      25184 :     jl_ast_ctx_leave(ctx);
     984                 :      25184 :     return res;
     985                 :            : }
     986                 :            : 
     987                 :     521561 : int jl_has_meta(jl_array_t *body, jl_sym_t *sym) JL_NOTSAFEPOINT
     988                 :            : {
     989                 :     521561 :     size_t i, l = jl_array_len(body);
     990         [ +  + ]:   44205700 :     for (i = 0; i < l; i++) {
     991                 :   43710600 :         jl_expr_t *stmt = (jl_expr_t*)jl_array_ptr_ref(body, i);
     992   [ +  +  +  + ]:   43710600 :         if (jl_is_expr((jl_value_t*)stmt) && stmt->head == jl_meta_sym) {
     993                 :      26850 :             size_t i, l = jl_array_len(stmt->args);
     994         [ +  + ]:      27266 :             for (i = 0; i < l; i++)
     995         [ +  + ]:      26915 :                 if (jl_array_ptr_ref(stmt->args, i) == (jl_value_t*)sym)
     996                 :      26499 :                     return 1;
     997                 :            :         }
     998                 :            :     }
     999                 :     495062 :     return 0;
    1000                 :            : }
    1001                 :            : 
    1002                 :      88060 : static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule, jl_module_t **ctx, size_t world, int throw_load_error)
    1003                 :            : {
    1004                 :      88060 :     jl_task_t *ct = jl_current_task;
    1005                 :            :     JL_TIMING(MACRO_INVOCATION);
    1006                 :      88060 :     size_t nargs = jl_array_len(args) + 1;
    1007         [ -  + ]:      88060 :     JL_NARGSV("macrocall", 3); // macro name, location, and module
    1008                 :            :     jl_value_t **margs;
    1009                 :      88060 :     JL_GC_PUSHARGS(margs, nargs);
    1010                 :            :     int i;
    1011                 :      88060 :     margs[0] = jl_array_ptr_ref(args, 0);
    1012                 :            :     // __source__ argument
    1013                 :      88060 :     jl_value_t *lno = jl_array_ptr_ref(args, 1);
    1014                 :      88060 :     margs[1] = lno;
    1015         [ +  + ]:      88060 :     if (!jl_typeis(lno, jl_linenumbernode_type)) {
    1016                 :       3806 :         margs[1] = jl_new_struct(jl_linenumbernode_type, jl_box_long(0), jl_nothing);
    1017                 :            :     }
    1018                 :      88060 :     margs[2] = (jl_value_t*)inmodule;
    1019         [ +  + ]:     195195 :     for (i = 3; i < nargs; i++)
    1020                 :     107135 :         margs[i] = jl_array_ptr_ref(args, i - 1);
    1021                 :            : 
    1022                 :      88060 :     size_t last_age = ct->world_age;
    1023                 :      88060 :     ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
    1024         [ +  + ]:      88060 :     if (ct->world_age > world)
    1025                 :          1 :         ct->world_age = world;
    1026                 :            :     jl_value_t *result;
    1027   [ +  +  +  + ]:     176077 :     JL_TRY {
    1028                 :      88060 :         margs[0] = jl_toplevel_eval(*ctx, margs[0]);
    1029                 :      88058 :         jl_method_instance_t *mfunc = jl_method_lookup(margs, nargs, world);
    1030                 :            :         JL_GC_PROMISE_ROOTED(mfunc);
    1031         [ +  + ]:      88058 :         if (mfunc == NULL) {
    1032                 :         12 :             jl_method_error(margs[0], &margs[1], nargs, world);
    1033                 :            :             // unreachable
    1034                 :            :         }
    1035                 :      88046 :         *ctx = mfunc->def.method->module;
    1036                 :      88046 :         result = jl_invoke(margs[0], &margs[1], nargs - 1, mfunc);
    1037                 :            :     }
    1038         [ +  - ]:         43 :     JL_CATCH {
    1039   [ +  -  +  + ]:         43 :         if ((jl_loaderror_type == NULL) || !throw_load_error) {
    1040                 :         36 :             jl_rethrow();
    1041                 :            :         }
    1042                 :            :         else {
    1043                 :          7 :             jl_value_t *lno = margs[1];
    1044                 :          7 :             jl_value_t *file = jl_fieldref(lno, 1);
    1045         [ +  - ]:          7 :             if (jl_is_symbol(file))
    1046                 :          7 :                 margs[0] = jl_cstr_to_string(jl_symbol_name((jl_sym_t*)file));
    1047                 :            :             else
    1048                 :          0 :                 margs[0] = jl_cstr_to_string("<macrocall>");
    1049                 :          7 :             margs[1] = jl_fieldref(lno, 0); // extract and allocate line number
    1050                 :          7 :             jl_rethrow_other(jl_new_struct(jl_loaderror_type, margs[0], margs[1],
    1051                 :            :                                            jl_current_exception()));
    1052                 :            :         }
    1053                 :            :     }
    1054                 :      88017 :     ct->world_age = last_age;
    1055                 :      88017 :     JL_GC_POP();
    1056                 :      88017 :     return result;
    1057                 :            : }
    1058                 :            : 
    1059                 :    9087750 : static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, struct macroctx_stack *macroctx, int onelevel, size_t world, int throw_load_error)
    1060                 :            : {
    1061   [ +  +  +  + ]:    9087750 :     if (!expr || !jl_is_expr(expr))
    1062                 :    5847000 :         return expr;
    1063                 :    3240740 :     jl_expr_t *e = (jl_expr_t*)expr;
    1064         [ +  + ]:    3240740 :     if (e->head == jl_inert_sym ||
    1065         [ +  + ]:    3149920 :         e->head == jl_module_sym ||
    1066                 :            :         //e->head == jl_toplevel_sym || // TODO: enable this once julia-expand-macroscope is fixed / removed
    1067         [ +  + ]:    3149760 :         e->head == jl_meta_sym) {
    1068                 :     110454 :         return expr;
    1069                 :            :     }
    1070   [ +  +  +  - ]:    3130290 :     if (e->head == jl_quote_sym && jl_expr_nargs(e) == 1) {
    1071                 :       8936 :         expr = jl_call_scm_on_ast("julia-bq-macro", jl_exprarg(e, 0), inmodule);
    1072                 :       8936 :         JL_GC_PUSH1(&expr);
    1073                 :       8936 :         expr = jl_expand_macros(expr, inmodule, macroctx, onelevel, world, throw_load_error);
    1074                 :       8936 :         JL_GC_POP();
    1075                 :       8936 :         return expr;
    1076                 :            :     }
    1077   [ +  +  +  - ]:    3121350 :     if (e->head == jl_hygienicscope_sym && jl_expr_nargs(e) == 2) {
    1078                 :            :         struct macroctx_stack newctx;
    1079                 :       3672 :         newctx.m = (jl_module_t*)jl_exprarg(e, 1);
    1080         [ -  + ]:       3672 :         JL_TYPECHK(hygienic-scope, module, (jl_value_t*)newctx.m);
    1081                 :       3672 :         newctx.parent = macroctx;
    1082                 :       3672 :         jl_value_t *a = jl_exprarg(e, 0);
    1083                 :       3672 :         jl_value_t *a2 = jl_expand_macros(a, inmodule, &newctx, onelevel, world, throw_load_error);
    1084         [ -  + ]:       3672 :         if (a != a2)
    1085                 :          0 :             jl_array_ptr_set(e->args, 0, a2);
    1086                 :       3672 :         return expr;
    1087                 :            :     }
    1088         [ +  + ]:    3117680 :     if (e->head == jl_macrocall_sym) {
    1089                 :            :         struct macroctx_stack newctx;
    1090         [ +  + ]:      88060 :         newctx.m = macroctx ? macroctx->m : inmodule;
    1091                 :      88060 :         newctx.parent = macroctx;
    1092                 :      88060 :         jl_value_t *result = jl_invoke_julia_macro(e->args, inmodule, &newctx.m, world, throw_load_error);
    1093                 :      88017 :         jl_value_t *wrap = NULL;
    1094                 :      88017 :         JL_GC_PUSH3(&result, &wrap, &newctx.m);
    1095                 :            :         // copy and wrap the result in `(hygienic-scope ,result ,newctx)
    1096   [ +  +  +  + ]:      88017 :         if (jl_is_expr(result) && ((jl_expr_t*)result)->head == jl_escape_sym)
    1097                 :      15903 :             result = jl_exprarg(result, 0);
    1098                 :            :         else
    1099                 :      72114 :             wrap = (jl_value_t*)jl_exprn(jl_hygienicscope_sym, 2);
    1100                 :      88017 :         result = jl_copy_ast(result);
    1101         [ +  + ]:      88017 :         if (!onelevel)
    1102         [ +  + ]:      87997 :             result = jl_expand_macros(result, inmodule, wrap ? &newctx : macroctx, onelevel, world, throw_load_error);
    1103         [ +  + ]:      88017 :         if (wrap) {
    1104                 :      72114 :             jl_exprargset(wrap, 0, result);
    1105                 :      72114 :             jl_exprargset(wrap, 1, newctx.m);
    1106                 :      72114 :             result = wrap;
    1107                 :            :         }
    1108                 :      88017 :         JL_GC_POP();
    1109                 :      88017 :         return result;
    1110                 :            :     }
    1111   [ +  +  +  -  :    3029620 :     if (e->head == jl_do_sym && jl_expr_nargs(e) == 2 && jl_is_expr(jl_exprarg(e, 0)) &&
                   +  - ]
    1112         [ +  + ]:       2012 :         ((jl_expr_t*)jl_exprarg(e, 0))->head == jl_macrocall_sym) {
    1113                 :          4 :         jl_expr_t *mc = (jl_expr_t*)jl_exprarg(e, 0);
    1114                 :          4 :         size_t nm = jl_expr_nargs(mc);
    1115                 :          4 :         jl_expr_t *mc2 = jl_exprn(jl_macrocall_sym, nm+1);
    1116                 :          4 :         JL_GC_PUSH1(&mc2);
    1117                 :          4 :         jl_exprargset(mc2, 0, jl_exprarg(mc, 0));  // macro name
    1118                 :          4 :         jl_exprargset(mc2, 1, jl_exprarg(mc, 1));  // location
    1119                 :          4 :         jl_exprargset(mc2, 2, jl_exprarg(e, 1));   // function argument
    1120                 :            :         size_t j;
    1121         [ +  + ]:          5 :         for (j = 2; j < nm; j++) {
    1122                 :          1 :             jl_exprargset(mc2, j+1, jl_exprarg(mc, j));
    1123                 :            :         }
    1124                 :          4 :         jl_value_t *ret = jl_expand_macros((jl_value_t*)mc2, inmodule, macroctx, onelevel, world, throw_load_error);
    1125                 :          4 :         JL_GC_POP();
    1126                 :          4 :         return ret;
    1127                 :            :     }
    1128   [ +  +  +  - ]:    3029620 :     if (e->head == jl_escape_sym && macroctx) {
    1129                 :     196484 :         macroctx = macroctx->parent;
    1130                 :            :     }
    1131                 :            : 
    1132                 :            :     size_t i;
    1133         [ +  + ]:   11889500 :     for (i = 0; i < jl_array_len(e->args); i++) {
    1134                 :    8859920 :         jl_value_t *a = jl_array_ptr_ref(e->args, i);
    1135                 :    8859920 :         jl_value_t *a2 = jl_expand_macros(a, inmodule, macroctx, onelevel, world, throw_load_error);
    1136         [ +  + ]:    8859910 :         if (a != a2)
    1137                 :      78670 :             jl_array_ptr_set(e->args, i, a2);
    1138                 :            :     }
    1139                 :    3029600 :     return expr;
    1140                 :            : }
    1141                 :            : 
    1142                 :       3776 : JL_DLLEXPORT jl_value_t *jl_macroexpand(jl_value_t *expr, jl_module_t *inmodule)
    1143                 :            : {
    1144                 :            :     JL_TIMING(LOWERING);
    1145                 :       3776 :     JL_GC_PUSH1(&expr);
    1146                 :       3776 :     expr = jl_copy_ast(expr);
    1147                 :       3776 :     expr = jl_expand_macros(expr, inmodule, NULL, 0, jl_atomic_load_acquire(&jl_world_counter), 0);
    1148                 :       3750 :     expr = jl_call_scm_on_ast("jl-expand-macroscope", expr, inmodule);
    1149                 :       3750 :     JL_GC_POP();
    1150                 :       3750 :     return expr;
    1151                 :            : }
    1152                 :            : 
    1153                 :         53 : JL_DLLEXPORT jl_value_t *jl_macroexpand1(jl_value_t *expr, jl_module_t *inmodule)
    1154                 :            : {
    1155                 :            :     JL_TIMING(LOWERING);
    1156                 :         53 :     JL_GC_PUSH1(&expr);
    1157                 :         53 :     expr = jl_copy_ast(expr);
    1158                 :         53 :     expr = jl_expand_macros(expr, inmodule, NULL, 1, jl_atomic_load_acquire(&jl_world_counter), 0);
    1159                 :         43 :     expr = jl_call_scm_on_ast("jl-expand-macroscope", expr, inmodule);
    1160                 :         43 :     JL_GC_POP();
    1161                 :         43 :     return expr;
    1162                 :            : }
    1163                 :            : 
    1164                 :            : // Lower an expression tree into Julia's intermediate-representation.
    1165                 :       6266 : JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr, jl_module_t *inmodule)
    1166                 :            : {
    1167                 :       6266 :     return jl_expand_with_loc(expr, inmodule, "none", 0);
    1168                 :            : }
    1169                 :            : 
    1170                 :            : // Lowering, with starting program location specified
    1171                 :       6266 : JL_DLLEXPORT jl_value_t *jl_expand_with_loc(jl_value_t *expr, jl_module_t *inmodule,
    1172                 :            :                                             const char *file, int line)
    1173                 :            : {
    1174                 :       6266 :     return jl_expand_in_world(expr, inmodule, file, line, ~(size_t)0);
    1175                 :            : }
    1176                 :            : 
    1177                 :            : // Lowering, with starting program location and worldage specified
    1178                 :       6267 : JL_DLLEXPORT jl_value_t *jl_expand_in_world(jl_value_t *expr, jl_module_t *inmodule,
    1179                 :            :                                             const char *file, int line, size_t world)
    1180                 :            : {
    1181                 :            :     JL_TIMING(LOWERING);
    1182                 :       6267 :     JL_GC_PUSH1(&expr);
    1183                 :       6267 :     expr = jl_copy_ast(expr);
    1184                 :       6267 :     expr = jl_expand_macros(expr, inmodule, NULL, 0, world, 1);
    1185                 :       6266 :     expr = jl_call_scm_on_ast_and_loc("jl-expand-to-thunk", expr, inmodule, file, line);
    1186                 :       6266 :     JL_GC_POP();
    1187                 :       6266 :     return expr;
    1188                 :            : }
    1189                 :            : 
    1190                 :            : // Same as the above, but printing warnings when applicable
    1191                 :      85749 : JL_DLLEXPORT jl_value_t *jl_expand_with_loc_warn(jl_value_t *expr, jl_module_t *inmodule,
    1192                 :            :                                                  const char *file, int line)
    1193                 :            : {
    1194                 :            :     JL_TIMING(LOWERING);
    1195                 :      85749 :     jl_array_t *kwargs = NULL;
    1196                 :      85749 :     JL_GC_PUSH2(&expr, &kwargs);
    1197                 :      85749 :     expr = jl_copy_ast(expr);
    1198                 :      85748 :     expr = jl_expand_macros(expr, inmodule, NULL, 0, ~(size_t)0, 1);
    1199                 :      85743 :     jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
    1200                 :      85747 :     fl_context_t *fl_ctx = &ctx->fl;
    1201                 :      85747 :     value_t arg = julia_to_scm(fl_ctx, expr);
    1202                 :      85747 :     value_t e = fl_applyn(fl_ctx, 4, symbol_value(symbol(fl_ctx, "jl-expand-to-thunk-warn")), arg,
    1203                 :      85746 :                           symbol(fl_ctx, file), fixnum(line), fl_ctx->F);
    1204                 :      85733 :     expr = scm_to_julia(fl_ctx, e, inmodule);
    1205                 :      85735 :     jl_ast_ctx_leave(ctx);
    1206                 :      85746 :     jl_sym_t *warn_sym = jl_symbol("warn");
    1207   [ +  +  -  + ]:      85741 :     if (jl_is_expr(expr) && ((jl_expr_t*)expr)->head == warn_sym) {
    1208                 :          0 :         size_t nargs = jl_expr_nargs(expr);
    1209         [ #  # ]:          0 :         for (int i = 0; i < nargs - 1; i++) {
    1210                 :          0 :             jl_value_t *warning = jl_exprarg(expr, i);
    1211                 :          0 :             size_t nargs = 0;
    1212   [ #  #  #  # ]:          0 :             if (jl_is_expr(warning) && ((jl_expr_t*)warning)->head == warn_sym)
    1213                 :          0 :                  nargs = jl_expr_nargs(warning);
    1214                 :          0 :             int kwargs_len = (int)nargs - 6;
    1215   [ #  #  #  # ]:          0 :             if (nargs < 6 || kwargs_len % 2 != 0) {
    1216                 :          0 :                 jl_error("julia-logmsg: bad argument list - expected "
    1217                 :            :                          ":warn level (symbol) group (symbol) id file line msg . kwargs");
    1218                 :            :             }
    1219                 :          0 :             jl_value_t *level = jl_exprarg(warning, 0);
    1220                 :          0 :             jl_value_t *group = jl_exprarg(warning, 1);
    1221                 :          0 :             jl_value_t *id = jl_exprarg(warning, 2);
    1222                 :          0 :             jl_value_t *file = jl_exprarg(warning, 3);
    1223                 :          0 :             jl_value_t *line = jl_exprarg(warning, 4);
    1224                 :          0 :             jl_value_t *msg = jl_exprarg(warning, 5);
    1225                 :          0 :             kwargs = jl_alloc_vec_any(kwargs_len);
    1226         [ #  # ]:          0 :             for (int i = 0; i < kwargs_len; ++i) {
    1227                 :          0 :                 jl_array_ptr_set(kwargs, i, jl_exprarg(warning, i + 6));
    1228                 :            :             }
    1229         [ #  # ]:          0 :             JL_TYPECHK(logmsg, long, level);
    1230                 :          0 :             jl_log(jl_unbox_long(level), NULL, group, id, file, line, (jl_value_t*)kwargs, msg);
    1231                 :            :         }
    1232                 :          0 :         expr = jl_exprarg(expr, nargs - 1);
    1233                 :            :     }
    1234                 :      85741 :     JL_GC_POP();
    1235                 :      85741 :     return expr;
    1236                 :            : }
    1237                 :            : 
    1238                 :            : // expand in a context where the expression value is unused
    1239                 :      31370 : JL_DLLEXPORT jl_value_t *jl_expand_stmt_with_loc(jl_value_t *expr, jl_module_t *inmodule,
    1240                 :            :                                                  const char *file, int line)
    1241                 :            : {
    1242                 :            :     JL_TIMING(LOWERING);
    1243                 :      31370 :     JL_GC_PUSH1(&expr);
    1244                 :      31370 :     expr = jl_copy_ast(expr);
    1245                 :      31370 :     expr = jl_expand_macros(expr, inmodule, NULL, 0, ~(size_t)0, 1);
    1246                 :      31370 :     expr = jl_call_scm_on_ast_and_loc("jl-expand-to-thunk-stmt", expr, inmodule, file, line);
    1247                 :      31370 :     JL_GC_POP();
    1248                 :      31370 :     return expr;
    1249                 :            : }
    1250                 :            : 
    1251                 :          0 : JL_DLLEXPORT jl_value_t *jl_expand_stmt(jl_value_t *expr, jl_module_t *inmodule)
    1252                 :            : {
    1253                 :          0 :     return jl_expand_stmt_with_loc(expr, inmodule, "none", 0);
    1254                 :            : }
    1255                 :            : 
    1256                 :            : 
    1257                 :            : //------------------------------------------------------------------------------
    1258                 :            : // Parsing API and utils for calling parser from runtime
    1259                 :            : 
    1260                 :            : // Internal C entry point to parser
    1261                 :            : // `text` is passed as a pointer to allow raw non-String buffers to be used
    1262                 :            : // without copying.
    1263                 :        238 : JL_DLLEXPORT jl_value_t *jl_parse(const char *text, size_t text_len, jl_value_t *filename,
    1264                 :            :                                   size_t lineno, size_t offset, jl_value_t *options)
    1265                 :            : {
    1266                 :        238 :     jl_value_t *core_parse = NULL;
    1267         [ +  - ]:        238 :     if (jl_core_module) {
    1268                 :        238 :         core_parse = jl_get_global(jl_core_module, jl_symbol("_parse"));
    1269                 :            :     }
    1270   [ +  +  +  + ]:        238 :     if (!core_parse || core_parse == jl_nothing) {
    1271                 :            :         // In bootstrap, directly call the builtin parser.
    1272                 :         65 :         jl_value_t *result = jl_fl_parse(text, text_len, filename, lineno, offset, options);
    1273                 :         65 :         return result;
    1274                 :            :     }
    1275                 :            :     jl_value_t **args;
    1276                 :        173 :     JL_GC_PUSHARGS(args, 6);
    1277                 :        173 :     args[0] = core_parse;
    1278                 :        173 :     args[1] = (jl_value_t*)jl_alloc_svec(2);
    1279                 :        173 :     jl_svecset(args[1], 0, jl_box_uint8pointer((uint8_t*)text));
    1280                 :        173 :     jl_svecset(args[1], 1, jl_box_long(text_len));
    1281                 :        173 :     args[2] = filename;
    1282                 :        173 :     args[3] = jl_box_ulong(lineno);
    1283                 :        173 :     args[4] = jl_box_ulong(offset);
    1284                 :        173 :     args[5] = options;
    1285                 :        173 :     jl_task_t *ct = jl_current_task;
    1286                 :        173 :     size_t last_age = ct->world_age;
    1287                 :        173 :     ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
    1288                 :        173 :     jl_value_t *result = jl_apply(args, 6);
    1289                 :        173 :     ct->world_age = last_age;
    1290                 :        173 :     args[0] = result; // root during error checks below
    1291         [ -  + ]:        173 :     JL_TYPECHK(parse, simplevector, result);
    1292         [ -  + ]:        173 :     if (jl_svec_len(result) != 2)
    1293                 :          0 :         jl_error("Result from parser should be `svec(a::Expr, b::Int)`");
    1294         [ -  + ]:        173 :     JL_TYPECHK(parse, expr, jl_svecref(result, 0));
    1295         [ -  + ]:        173 :     JL_TYPECHK(parse, long, jl_svecref(result, 1));
    1296                 :        173 :     JL_GC_POP();
    1297                 :        173 :     return result;
    1298                 :            : }
    1299                 :            : 
    1300                 :            : // parse an entire string as a file, reading multiple expressions
    1301                 :          0 : JL_DLLEXPORT jl_value_t *jl_parse_all(const char *text, size_t text_len,
    1302                 :            :                                       const char *filename, size_t filename_len, size_t lineno)
    1303                 :            : {
    1304                 :          0 :     jl_value_t *fname = jl_pchar_to_string(filename, filename_len);
    1305                 :          0 :     JL_GC_PUSH1(&fname);
    1306                 :          0 :     jl_value_t *p = jl_parse(text, text_len, fname, lineno, 0, (jl_value_t*)jl_all_sym);
    1307                 :          0 :     JL_GC_POP();
    1308                 :          0 :     return jl_svecref(p, 0);
    1309                 :            : }
    1310                 :            : 
    1311                 :            : // this is for parsing one expression out of a string, keeping track of
    1312                 :            : // the current position.
    1313                 :          0 : JL_DLLEXPORT jl_value_t *jl_parse_string(const char *text, size_t text_len,
    1314                 :            :                                          int offset, int greedy)
    1315                 :            : {
    1316                 :          0 :     jl_value_t *fname = jl_cstr_to_string("none");
    1317                 :          0 :     JL_GC_PUSH1(&fname);
    1318         [ #  # ]:          0 :     jl_value_t *result = jl_parse(text, text_len, fname, 1, offset,
    1319                 :            :                                   (jl_value_t*)(greedy ? jl_statement_sym : jl_atom_sym));
    1320                 :          0 :     JL_GC_POP();
    1321                 :          0 :     return result;
    1322                 :            : }
    1323                 :            : 
    1324                 :            : // deprecated
    1325                 :          0 : JL_DLLEXPORT jl_value_t *jl_parse_input_line(const char *text, size_t text_len,
    1326                 :            :                                              const char *filename, size_t filename_len)
    1327                 :            : {
    1328                 :          0 :     return jl_parse_all(text, text_len, filename, filename_len, 1);
    1329                 :            : }
    1330                 :            : 
    1331                 :            : #ifdef __cplusplus
    1332                 :            : }
    1333                 :            : #endif

Generated by: LCOV version 1.14