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 : 426 : 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 : 426 : argcount(fl_ctx, "defined-julia-global", nargs, 1);
156 : 426 : (void)tosymbol(fl_ctx, args[0], "defined-julia-global");
157 : 426 : jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx);
158 : 426 : jl_sym_t *var = jl_symbol(symbol_name(fl_ctx, args[0]));
159 : 426 : jl_binding_t *b = jl_get_module_binding(ctx->module, var);
160 [ + + + + ]: 426 : return (b != NULL && b->owner == ctx->module) ? fl_ctx->T : fl_ctx->F;
161 : : }
162 : :
163 : 9511 : static value_t fl_current_module_counter(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT
164 : : {
165 : 9511 : jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx);
166 [ - + ]: 9511 : assert(ctx->module);
167 : 9511 : return fixnum(jl_module_next_counter(ctx->module));
168 : : }
169 : :
170 : 0 : static value_t fl_julia_current_file(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT
171 : : {
172 : 0 : return symbol(fl_ctx, jl_filename);
173 : : }
174 : :
175 : 0 : static value_t fl_julia_current_line(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT
176 : : {
177 : 0 : 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 : 15 : static void jl_init_ast_ctx(jl_ast_context_t *ctx) JL_NOTSAFEPOINT
217 : : {
218 : 15 : fl_context_t *fl_ctx = &ctx->fl;
219 : 15 : fl_init(fl_ctx, 4*1024*1024);
220 : :
221 [ - + ]: 15 : 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 : 15 : fl_applyn(fl_ctx, 0, symbol_value(symbol(fl_ctx, "__init_globals")));
227 : :
228 : 15 : ctx->jvtype = define_opaque_type(fl_ctx->jl_sym, sizeof(void*), NULL, NULL);
229 : 15 : assign_global_builtins(fl_ctx, julia_flisp_ast_ext);
230 : 15 : ctx->true_sym = symbol(fl_ctx, "true");
231 : 15 : ctx->false_sym = symbol(fl_ctx, "false");
232 : 15 : ctx->error_sym = symbol(fl_ctx, "error");
233 : 15 : ctx->null_sym = symbol(fl_ctx, "null");
234 : 15 : ctx->ssavalue_sym = symbol(fl_ctx, "ssavalue");
235 : 15 : ctx->slot_sym = symbol(fl_ctx, "slot");
236 : 15 : ctx->module = NULL;
237 : 15 : set(symbol(fl_ctx, "*scopewarn-opt*"), fixnum(jl_options.warn_scope));
238 : 15 : }
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 : 104700 : static jl_ast_context_t *jl_ast_ctx_enter(jl_module_t *m) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT
245 : : {
246 : 104700 : JL_SIGATOMIC_BEGIN();
247 : 104700 : uv_mutex_lock(&flisp_lock);
248 : 104700 : jl_ast_context_t *ctx = jl_ast_ctx_freed;
249 [ + - ]: 104700 : if (ctx != NULL) {
250 : 104700 : jl_ast_ctx_freed = ctx->next;
251 : 104700 : ctx->next = NULL;
252 : : }
253 : 104700 : uv_mutex_unlock(&flisp_lock);
254 [ - + ]: 104700 : if (ctx == NULL) {
255 : : // Construct a new one if we can't find any
256 : 0 : ctx = (jl_ast_context_t*)calloc(1, sizeof(jl_ast_context_t));
257 : 0 : jl_init_ast_ctx(ctx);
258 : : }
259 : 104700 : ctx->module = m;
260 : 104700 : return ctx;
261 : : }
262 : :
263 : 104715 : static void jl_ast_ctx_leave(jl_ast_context_t *ctx)
264 : : {
265 : 104715 : uv_mutex_lock(&flisp_lock);
266 : 104715 : ctx->module = NULL;
267 : 104715 : ctx->next = jl_ast_ctx_freed;
268 : 104715 : jl_ast_ctx_freed = ctx;
269 : 104715 : uv_mutex_unlock(&flisp_lock);
270 [ + + ]: 104715 : JL_SIGATOMIC_END();
271 : 104715 : }
272 : :
273 : 15 : void jl_init_flisp(void)
274 : : {
275 [ - + ]: 15 : if (jl_ast_ctx_freed)
276 : 0 : return;
277 : 15 : uv_mutex_init(&flisp_lock);
278 : 15 : jl_init_ast_ctx(&jl_ast_main_ctx);
279 : : // To match the one in jl_ast_ctx_leave
280 : 15 : JL_SIGATOMIC_BEGIN();
281 : 15 : jl_ast_ctx_leave(&jl_ast_main_ctx);
282 : : }
283 : :
284 : 15 : void jl_init_common_symbols(void)
285 : : {
286 : 15 : jl_empty_sym = jl_symbol("");
287 : 15 : jl_call_sym = jl_symbol("call");
288 : 15 : jl_invoke_sym = jl_symbol("invoke");
289 : 15 : jl_invoke_modify_sym = jl_symbol("invoke_modify");
290 : 15 : jl_foreigncall_sym = jl_symbol("foreigncall");
291 : 15 : jl_cfunction_sym = jl_symbol("cfunction");
292 : 15 : jl_quote_sym = jl_symbol("quote");
293 : 15 : jl_inert_sym = jl_symbol("inert");
294 : 15 : jl_top_sym = jl_symbol("top");
295 : 15 : jl_core_sym = jl_symbol("core");
296 : 15 : jl_globalref_sym = jl_symbol("globalref");
297 : 15 : jl_line_sym = jl_symbol("line");
298 : 15 : jl_lineinfo_sym = jl_symbol("lineinfo");
299 : 15 : jl_incomplete_sym = jl_symbol("incomplete");
300 : 15 : jl_error_sym = jl_symbol("error");
301 : 15 : jl_goto_sym = jl_symbol("goto");
302 : 15 : jl_goto_ifnot_sym = jl_symbol("gotoifnot");
303 : 15 : jl_return_sym = jl_symbol("return");
304 : 15 : jl_lambda_sym = jl_symbol("lambda");
305 : 15 : jl_module_sym = jl_symbol("module");
306 : 15 : jl_export_sym = jl_symbol("export");
307 : 15 : jl_import_sym = jl_symbol("import");
308 : 15 : jl_using_sym = jl_symbol("using");
309 : 15 : jl_assign_sym = jl_symbol("=");
310 : 15 : jl_method_sym = jl_symbol("method");
311 : 15 : jl_exc_sym = jl_symbol("the_exception");
312 : 15 : jl_enter_sym = jl_symbol("enter");
313 : 15 : jl_leave_sym = jl_symbol("leave");
314 : 15 : jl_pop_exception_sym = jl_symbol("pop_exception");
315 : 15 : jl_new_sym = jl_symbol("new");
316 : 15 : jl_splatnew_sym = jl_symbol("splatnew");
317 : 15 : jl_new_opaque_closure_sym = jl_symbol("new_opaque_closure");
318 : 15 : jl_opaque_closure_method_sym = jl_symbol("opaque_closure_method");
319 : 15 : jl_const_sym = jl_symbol("const");
320 : 15 : jl_global_sym = jl_symbol("global");
321 : 15 : jl_thunk_sym = jl_symbol("thunk");
322 : 15 : jl_toplevel_sym = jl_symbol("toplevel");
323 : 15 : jl_dot_sym = jl_symbol(".");
324 : 15 : jl_as_sym = jl_symbol("as");
325 : 15 : jl_colon_sym = jl_symbol(":");
326 : 15 : jl_boundscheck_sym = jl_symbol("boundscheck");
327 : 15 : jl_inbounds_sym = jl_symbol("inbounds");
328 : 15 : jl_newvar_sym = jl_symbol("newvar");
329 : 15 : jl_copyast_sym = jl_symbol("copyast");
330 : 15 : jl_loopinfo_sym = jl_symbol("loopinfo");
331 : 15 : jl_pure_sym = jl_symbol("pure");
332 : 15 : jl_meta_sym = jl_symbol("meta");
333 : 15 : jl_list_sym = jl_symbol("list");
334 : 15 : jl_unused_sym = jl_symbol("#unused#");
335 : 15 : jl_slot_sym = jl_symbol("slot");
336 : 15 : jl_static_parameter_sym = jl_symbol("static_parameter");
337 : 15 : jl_inline_sym = jl_symbol("inline");
338 : 15 : jl_noinline_sym = jl_symbol("noinline");
339 : 15 : jl_polly_sym = jl_symbol("polly");
340 : 15 : jl_propagate_inbounds_sym = jl_symbol("propagate_inbounds");
341 : 15 : jl_aggressive_constprop_sym = jl_symbol("aggressive_constprop");
342 : 15 : jl_no_constprop_sym = jl_symbol("no_constprop");
343 : 15 : jl_purity_sym = jl_symbol("purity");
344 : 15 : jl_isdefined_sym = jl_symbol("isdefined");
345 : 15 : jl_nospecialize_sym = jl_symbol("nospecialize");
346 : 15 : jl_specialize_sym = jl_symbol("specialize");
347 : 15 : jl_optlevel_sym = jl_symbol("optlevel");
348 : 15 : jl_compile_sym = jl_symbol("compile");
349 : 15 : jl_force_compile_sym = jl_symbol("force_compile");
350 : 15 : jl_infer_sym = jl_symbol("infer");
351 : 15 : jl_max_methods_sym = jl_symbol("max_methods");
352 : 15 : jl_macrocall_sym = jl_symbol("macrocall");
353 : 15 : jl_escape_sym = jl_symbol("escape");
354 : 15 : jl_hygienicscope_sym = jl_symbol("hygienic-scope");
355 : 15 : jl_gc_preserve_begin_sym = jl_symbol("gc_preserve_begin");
356 : 15 : jl_gc_preserve_end_sym = jl_symbol("gc_preserve_end");
357 : 15 : jl_generated_sym = jl_symbol("generated");
358 : 15 : jl_generated_only_sym = jl_symbol("generated_only");
359 : 15 : jl_throw_undef_if_not_sym = jl_symbol("throw_undef_if_not");
360 : 15 : jl_getfield_undefref_sym = jl_symbol("##getfield##");
361 : 15 : jl_do_sym = jl_symbol("do");
362 : 15 : jl_coverageeffect_sym = jl_symbol("code_coverage_effect");
363 : 15 : jl_aliasscope_sym = jl_symbol("aliasscope");
364 : 15 : jl_popaliasscope_sym = jl_symbol("popaliasscope");
365 : 15 : jl_thismodule_sym = jl_symbol("thismodule");
366 : 15 : jl_block_sym = jl_symbol("block");
367 : 15 : jl_atom_sym = jl_symbol("atom");
368 : 15 : jl_statement_sym = jl_symbol("statement");
369 : 15 : jl_all_sym = jl_symbol("all");
370 : 15 : jl_atomic_sym = jl_symbol("atomic");
371 : 15 : jl_not_atomic_sym = jl_symbol("not_atomic");
372 : 15 : jl_unordered_sym = jl_symbol("unordered");
373 : 15 : jl_monotonic_sym = jl_symbol("monotonic");
374 : 15 : jl_acquire_sym = jl_symbol("acquire");
375 : 15 : jl_release_sym = jl_symbol("release");
376 : 15 : jl_acquire_release_sym = jl_symbol("acquire_release");
377 : 15 : jl_sequentially_consistent_sym = jl_symbol("sequentially_consistent");
378 : 15 : }
379 : :
380 : 0 : 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 : 0 : JL_SIGATOMIC_BEGIN();
385 : 0 : jl_init_flisp();
386 : 0 : jl_ast_context_t *ctx = jl_ast_ctx_enter(jl_main_module);
387 : 0 : fl_context_t *fl_ctx = &ctx->fl;
388 : 0 : 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 : 13292100 : static jl_sym_t *scmsym_to_julia(fl_context_t *fl_ctx, value_t s)
418 : : {
419 [ - + ]: 13292100 : assert(issymbol(s));
420 [ - + ]: 13292100 : 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 : 13292100 : return jl_symbol(symbol_name(fl_ctx, s));
428 : : }
429 : :
430 : 180576 : static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mod)
431 : : {
432 : 180576 : jl_value_t *v = NULL;
433 : 180576 : JL_GC_PUSH1(&v);
434 [ + - + + ]: 361152 : JL_TRY {
435 : 180576 : 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 : 180576 : JL_GC_POP();
444 : 180576 : return v;
445 : : }
446 : :
447 : : extern int64_t conv_to_int64(void *data, numerictype_t tag);
448 : :
449 : 19044500 : static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *mod)
450 : : {
451 [ + + ]: 19044500 : if (fl_isnumber(fl_ctx, e)) {
452 : : int64_t i64;
453 [ + + ]: 3663080 : if (isfixnum(e)) {
454 : 3653890 : i64 = numval(e);
455 : : }
456 : : else {
457 [ - + ]: 9182 : assert(iscprim(e));
458 : 9182 : cprim_t *cp = (cprim_t*)ptr(e);
459 : 9182 : numerictype_t nt = cp_numtype(cp);
460 [ + + + + : 9182 : switch (nt) {
+ + + ]
461 : 4424 : case T_DOUBLE:
462 : 4424 : return (jl_value_t*)jl_box_float64(*(double*)cp_data(cp));
463 : 342 : case T_FLOAT:
464 : 342 : return (jl_value_t*)jl_box_float32(*(float*)cp_data(cp));
465 : 853 : case T_UINT8:
466 : 853 : return (jl_value_t*)jl_box_uint8(*(uint8_t*)cp_data(cp));
467 : 370 : case T_UINT16:
468 : 370 : return (jl_value_t*)jl_box_uint16(*(uint16_t*)cp_data(cp));
469 : 755 : case T_UINT32:
470 : 755 : return (jl_value_t*)jl_box_uint32(*(uint32_t*)cp_data(cp));
471 : 2432 : case T_UINT64:
472 : 2432 : return (jl_value_t*)jl_box_uint64(*(uint64_t*)cp_data(cp));
473 : 6 : default:
474 : : ;
475 : : }
476 : 6 : i64 = conv_to_int64(cp_data(cp), nt);
477 : : }
478 : : #ifdef _P64
479 : 3653900 : 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 [ + + ]: 15381400 : if (issymbol(e))
488 : 5507090 : return (jl_value_t*)scmsym_to_julia(fl_ctx, e);
489 [ + + ]: 9874320 : if (fl_isstring(fl_ctx, e))
490 : 51961 : return jl_pchar_to_string((char*)cvalue_data(e), cvalue_len(e));
491 [ + + - + ]: 9822360 : if (iscons(e) || e == fl_ctx->NIL) {
492 : : value_t hd;
493 : : jl_sym_t *sym;
494 [ - + ]: 9608230 : if (e == fl_ctx->NIL) {
495 : 0 : hd = e;
496 : : }
497 : : else {
498 : 9608230 : hd = car_(e);
499 [ + + ]: 9608230 : if (hd == jl_ast_ctx(fl_ctx)->ssavalue_sym)
500 : 1083890 : return jl_box_ssavalue(numval(car_(cdr_(e))));
501 [ + + ]: 8524340 : else if (hd == jl_ast_ctx(fl_ctx)->slot_sym)
502 : 641668 : return jl_box_slotnumber(numval(car_(cdr_(e))));
503 [ + + + - ]: 7882670 : else if (hd == jl_ast_ctx(fl_ctx)->null_sym && llength(e) == 1)
504 : 44125 : return jl_nothing;
505 [ + + + - ]: 7838550 : else if (hd == jl_ast_ctx(fl_ctx)->true_sym && llength(e) == 1)
506 : 17968 : return jl_true;
507 [ + + + - ]: 7820580 : else if (hd == jl_ast_ctx(fl_ctx)->false_sym && llength(e) == 1)
508 : 34888 : return jl_false;
509 [ + + + - ]: 7785690 : else if (hd == fl_ctx->jl_char_sym && llength(e) == 2) {
510 : 668 : value_t v = car_(cdr_(e));
511 [ + - - + ]: 668 : if (!(iscprim(v) && cp_class((cprim_t*)ptr(v)) == fl_ctx->uint32type))
512 : 0 : jl_error("malformed julia char");
513 : 668 : uint32_t c = *(uint32_t*)cp_data((cprim_t*)ptr(v));
514 : 668 : return jl_box_char(c);
515 : : }
516 : : }
517 [ + - ]: 7785020 : if (issymbol(hd))
518 : 7785020 : sym = scmsym_to_julia(fl_ctx, hd);
519 : : else
520 : 0 : sym = jl_list_sym;
521 : 7785020 : size_t n = llength(e)-1;
522 [ + - ]: 7785020 : if (issymbol(hd))
523 : 7785020 : e = cdr_(e);
524 : : else
525 : 0 : n++;
526 : : // nodes with special representations
527 : 7785020 : jl_value_t *ex = NULL, *temp = NULL;
528 [ + + + - : 7785020 : if (sym == jl_line_sym && (n == 1 || n == 2)) {
+ - ]
529 : 490582 : jl_value_t *linenum = scm_to_julia_(fl_ctx, car_(e), mod);
530 : 490582 : jl_value_t *file = jl_nothing;
531 : 490582 : JL_GC_PUSH2(&linenum, &file);
532 [ + - ]: 490582 : if (n == 2)
533 : 490582 : file = scm_to_julia_(fl_ctx, car_(cdr_(e)), mod);
534 : 490582 : temp = jl_new_struct(jl_linenumbernode_type, linenum, file);
535 : 490582 : JL_GC_POP();
536 : 490582 : return temp;
537 : : }
538 [ + + + - ]: 7294440 : else if (sym == jl_lineinfo_sym && n == 5) {
539 : 320843 : jl_value_t *modu=NULL, *name=NULL, *file=NULL, *linenum=NULL, *inlinedat=NULL;
540 : 320843 : JL_GC_PUSH5(&modu, &name, &file, &linenum, &inlinedat);
541 : 320843 : value_t lst = e;
542 : 320843 : modu = scm_to_julia_(fl_ctx, car_(lst), mod);
543 : 320843 : lst = cdr_(lst);
544 : 320843 : name = scm_to_julia_(fl_ctx, car_(lst), mod);
545 : 320843 : lst = cdr_(lst);
546 : 320843 : file = scm_to_julia_(fl_ctx, car_(lst), mod);
547 : 320843 : lst = cdr_(lst);
548 : 320843 : linenum = scm_to_julia_(fl_ctx, car_(lst), mod);
549 : 320843 : lst = cdr_(lst);
550 : 320843 : inlinedat = scm_to_julia_(fl_ctx, car_(lst), mod);
551 : 320843 : temp = jl_new_struct(jl_lineinfonode_type, modu, name, file, linenum, inlinedat);
552 : 320843 : JL_GC_POP();
553 : 320843 : return temp;
554 : : }
555 : 6973600 : JL_GC_PUSH2(&ex, &temp);
556 [ + + ]: 6973600 : if (sym == jl_goto_sym) {
557 : 44951 : ex = scm_to_julia_(fl_ctx, car_(e), mod);
558 : 44951 : temp = jl_new_struct(jl_gotonode_type, ex);
559 : : }
560 [ + + ]: 6928650 : else if (sym == jl_goto_ifnot_sym) {
561 : 80620 : ex = scm_to_julia_(fl_ctx, car_(e), mod);
562 : 80620 : temp = scm_to_julia(fl_ctx, car_(cdr_(e)), mod);
563 : 80620 : temp = jl_new_struct(jl_gotoifnot_type, ex, temp);
564 : : }
565 [ + + ]: 6848030 : else if (sym == jl_newvar_sym) {
566 : 37204 : ex = scm_to_julia_(fl_ctx, car_(e), mod);
567 : 37204 : temp = jl_new_struct(jl_newvarnode_type, ex);
568 : : }
569 [ + + ]: 6810820 : else if (sym == jl_globalref_sym) {
570 : 21138 : ex = scm_to_julia_(fl_ctx, car_(e), mod);
571 : 21138 : temp = scm_to_julia_(fl_ctx, car_(cdr_(e)), mod);
572 [ - + ]: 21138 : assert(jl_is_module(ex));
573 [ - + ]: 21138 : assert(jl_is_symbol(temp));
574 : 21138 : temp = jl_module_globalref((jl_module_t*)ex, (jl_sym_t*)temp);
575 : : }
576 [ + + ]: 6789690 : else if (sym == jl_top_sym) {
577 [ - + ]: 199293 : assert(mod && "top should not be generated by the parser");
578 : 199293 : ex = scm_to_julia_(fl_ctx, car_(e), mod);
579 [ - + ]: 199293 : assert(jl_is_symbol(ex));
580 : 199293 : temp = jl_module_globalref(jl_base_relative_to(mod), (jl_sym_t*)ex);
581 : : }
582 [ + + ]: 6590390 : else if (sym == jl_core_sym) {
583 : 913514 : ex = scm_to_julia_(fl_ctx, car_(e), mod);
584 [ - + ]: 913514 : assert(jl_is_symbol(ex));
585 : 913514 : temp = jl_module_globalref(jl_core_module, (jl_sym_t*)ex);
586 : : }
587 [ + + ]: 5676880 : else if (sym == jl_thismodule_sym) {
588 : 327101 : temp = (jl_value_t*)mod;
589 : : }
590 [ + + + + : 5349780 : else if (iscons(e) && (sym == jl_inert_sym || (sym == jl_quote_sym && (!iscons(car_(e)))))) {
+ + + + ]
591 : 472080 : ex = scm_to_julia_(fl_ctx, car_(e), mod);
592 : 472080 : temp = jl_new_struct(jl_quotenode_type, ex);
593 : : }
594 [ + + ]: 6973600 : if (temp) {
595 : 2095900 : JL_GC_POP();
596 : 2095900 : return temp;
597 : : }
598 : 4877700 : ex = (jl_value_t*)jl_exprn(sym, n);
599 : : size_t i;
600 [ + + ]: 19366300 : for (i = 0; i < n; i++) {
601 [ - + ]: 14488600 : assert(iscons(e));
602 : 14488600 : jl_array_ptr_set(((jl_expr_t*)ex)->args, i, scm_to_julia_(fl_ctx, car_(e), mod));
603 : 14488600 : e = cdr_(e);
604 : : }
605 [ + + ]: 4877700 : if (sym == jl_lambda_sym)
606 : 162580 : ex = (jl_value_t*)jl_new_code_info_from_ir((jl_expr_t*)ex);
607 : 4877700 : JL_GC_POP();
608 [ + + ]: 4877700 : if (sym == jl_list_sym)
609 : 1419670 : return (jl_value_t*)((jl_expr_t*)ex)->args;
610 : 3458020 : return (jl_value_t*)ex;
611 : : }
612 [ + + + - ]: 214130 : if (iscprim(e) && cp_class((cprim_t*)ptr(e)) == fl_ctx->wchartype) {
613 : 4499 : uint32_t c, u = *(uint32_t*)cp_data((cprim_t*)ptr(e));
614 [ + + ]: 4499 : if (u < 0x80) {
615 : 4455 : c = u << 24;
616 : : } else {
617 : 44 : c = ((u << 0) & 0x0000003f) | ((u << 2) & 0x00003f00) |
618 : 44 : ((u << 4) & 0x003f0000) | ((u << 6) & 0x3f000000);
619 [ + + ]: 84 : c = u < 0x00000800 ? (c << 16) | 0xc0800000 :
620 [ + - ]: 40 : u < 0x00010000 ? (c << 8) | 0xe0808000 :
621 : : (c << 0) | 0xf0808080 ;
622 : : }
623 : 4499 : return jl_box_char(c);
624 : : }
625 [ + - + - ]: 209631 : if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jl_ast_ctx(fl_ctx)->jvtype) {
626 : 209631 : 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 : 94007 : 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 [ + - + + ]: 188014 : FL_TRY_EXTERN(fl_ctx) {
638 : 94007 : temp = julia_to_scm_(fl_ctx, v, 1);
639 : : }
640 [ # # ]: 0 : FL_CATCH_EXTERN(fl_ctx) {
641 : 0 : temp = fl_ctx->lasterror;
642 : : }
643 : 94007 : return temp;
644 : : }
645 : :
646 : 1885650 : 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 [ + + ]: 6708040 : for(long i=jl_array_len(a)-1; i >= 0; i--) {
650 : 4822390 : *pv = fl_cons(fl_ctx, fl_ctx->NIL, *pv);
651 : 4822390 : temp = julia_to_scm_(fl_ctx, jl_array_ptr_ref(a,i), check_valid);
652 : : // note: must be separate statement
653 : 4822390 : car_(*pv) = temp;
654 : : }
655 : 1885650 : }
656 : :
657 : 249039 : static value_t julia_to_list2(fl_context_t *fl_ctx, jl_value_t *a, jl_value_t *b, int check_valid)
658 : : {
659 : 249039 : value_t sa = julia_to_scm_(fl_ctx, a, check_valid);
660 : 249039 : fl_gc_handle(fl_ctx, &sa);
661 : 249039 : value_t sb = julia_to_scm_(fl_ctx, b, check_valid);
662 : 249039 : value_t l = fl_list2(fl_ctx, sa, sb);
663 : 249039 : fl_free_gc_handles(fl_ctx, 1);
664 : 249039 : return l;
665 : : }
666 : :
667 : 8734300 : static int julia_to_scm_noalloc1(fl_context_t *fl_ctx, jl_value_t *v, value_t *retval) JL_NOTSAFEPOINT
668 : : {
669 [ - + ]: 8734300 : if (v == NULL)
670 : 0 : lerror(fl_ctx, symbol(fl_ctx, "error"), "undefined reference in AST");
671 [ + + ]: 8734300 : else if (jl_is_symbol(v))
672 : 5276200 : *retval = symbol(fl_ctx, jl_symbol_name((jl_sym_t*)v));
673 [ + + ]: 3458100 : else if (v == jl_true)
674 : 13578 : *retval = fl_cons(fl_ctx, jl_ast_ctx(fl_ctx)->true_sym, fl_ctx->NIL);
675 [ + + ]: 3444520 : else if (v == jl_false)
676 : 15380 : *retval = fl_cons(fl_ctx, jl_ast_ctx(fl_ctx)->false_sym, fl_ctx->NIL);
677 [ + + ]: 3429140 : else if (v == jl_nothing)
678 : 6849 : *retval = fl_cons(fl_ctx, jl_ast_ctx(fl_ctx)->null_sym, fl_ctx->NIL);
679 : : else
680 : 3422300 : return 0;
681 : 5312000 : return 1;
682 : : }
683 : :
684 : 811899 : static value_t julia_to_scm_noalloc2(fl_context_t *fl_ctx, jl_value_t *v, int check_valid) JL_NOTSAFEPOINT
685 : : {
686 [ + + + + : 811899 : if (jl_is_long(v) && fits_fixnum(jl_unbox_long(v)))
+ + ]
687 : 579287 : return fixnum(jl_unbox_long(v));
688 [ + + ]: 232612 : if (check_valid) {
689 [ - + ]: 227572 : if (jl_is_ssavalue(v))
690 : 0 : lerror(fl_ctx, symbol(fl_ctx, "error"), "SSAValue objects should not occur in an AST");
691 [ + - - + ]: 227572 : if (jl_is_slot(v))
692 : 0 : lerror(fl_ctx, symbol(fl_ctx, "error"), "Slot objects should not occur in an AST");
693 : : }
694 : 232612 : value_t opaque = cvalue(fl_ctx, jl_ast_ctx(fl_ctx)->jvtype, sizeof(void*));
695 : 232612 : *(jl_value_t**)cv_data((cvalue_t*)ptr(opaque)) = v;
696 : 232612 : return opaque;
697 : : }
698 : :
699 : 953698 : 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 [ + + ]: 953698 : if (julia_to_scm_noalloc1(fl_ctx, v, &retval))
703 : 476849 : return retval;
704 [ + - + - : 476849 : 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 : 476849 : return julia_to_scm_noalloc2(fl_ctx, v, check_valid);
711 : : }
712 : :
713 : 476849 : 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 : 476849 : value_t sa = julia_to_scm_noalloc(fl_ctx, a, check_valid);
716 : 476849 : fl_gc_handle(fl_ctx, &sa);
717 : 476849 : value_t sb = julia_to_scm_noalloc(fl_ctx, b, check_valid);
718 : 476849 : value_t l = fl_list2(fl_ctx, sa, sb);
719 : 476849 : fl_free_gc_handles(fl_ctx, 1);
720 : 476849 : return l;
721 : : }
722 : :
723 : 7780600 : static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v, int check_valid)
724 : : {
725 : : value_t retval;
726 [ + + ]: 7780600 : if (julia_to_scm_noalloc1(fl_ctx, v, &retval))
727 : 4835150 : return retval;
728 [ + + ]: 2945450 : if (jl_is_expr(v)) {
729 : 1884510 : jl_expr_t *ex = (jl_expr_t*)v;
730 : 1884510 : value_t args = fl_ctx->NIL;
731 : 1884510 : fl_gc_handle(fl_ctx, &args);
732 [ - + - - ]: 1884510 : if (jl_expr_nargs(ex) > 520000 && ex->head != jl_block_sym)
733 : 0 : lerror(fl_ctx, symbol(fl_ctx, "error"), "expression too large");
734 : 1884510 : array_to_list(fl_ctx, ex->args, &args, check_valid);
735 : 1884510 : value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)ex->head, check_valid);
736 [ + + + - : 1884510 : if (ex->head == jl_lambda_sym && jl_expr_nargs(ex)>0 && jl_is_array(jl_exprarg(ex,0))) {
+ - ]
737 : 1139 : value_t llist = fl_ctx->NIL;
738 : 1139 : fl_gc_handle(fl_ctx, &llist);
739 : 1139 : array_to_list(fl_ctx, (jl_array_t*)jl_exprarg(ex,0), &llist, check_valid);
740 : 1139 : car_(args) = llist;
741 : 1139 : fl_free_gc_handles(fl_ctx, 1);
742 : : }
743 : 1884510 : value_t scmv = fl_cons(fl_ctx, hd, args);
744 : 1884510 : fl_free_gc_handles(fl_ctx, 1);
745 : 1884510 : 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 [ + + ]: 1060940 : if (jl_typeis(v, jl_linenumbernode_type)) {
751 : 476849 : jl_value_t *file = jl_fieldref_noalloc(v,1);
752 : 476849 : jl_value_t *line = jl_fieldref(v,0);
753 : 476849 : value_t args = julia_to_list2_noalloc(fl_ctx, line, file, check_valid);
754 : 476849 : fl_gc_handle(fl_ctx, &args);
755 : 476849 : value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)jl_line_sym, check_valid);
756 : 476849 : value_t scmv = fl_cons(fl_ctx, hd, args);
757 : 476849 : fl_free_gc_handles(fl_ctx, 1);
758 : 476849 : return scmv;
759 : : }
760 [ - + ]: 584089 : 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 [ + + ]: 584089 : if (jl_typeis(v, jl_quotenode_type))
763 : 220348 : return julia_to_list2(fl_ctx, (jl_value_t*)jl_inert_sym, jl_fieldref_noalloc(v,0), 0);
764 [ - + ]: 363741 : 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 [ + + ]: 363741 : if (jl_typeis(v, jl_globalref_type)) {
767 : 28691 : jl_module_t *m = jl_globalref_mod(v);
768 : 28691 : jl_sym_t *sym = jl_globalref_name(v);
769 [ + + ]: 28691 : if (m == jl_core_module)
770 : 23927 : return julia_to_list2(fl_ctx, (jl_value_t*)jl_core_sym,
771 : : (jl_value_t*)sym, check_valid);
772 : 4764 : value_t args = julia_to_list2(fl_ctx, (jl_value_t*)m, (jl_value_t*)sym, check_valid);
773 : 4764 : fl_gc_handle(fl_ctx, &args);
774 : 4764 : value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)jl_globalref_sym, check_valid);
775 : 4764 : value_t scmv = fl_cons(fl_ctx, hd, args);
776 : 4764 : fl_free_gc_handles(fl_ctx, 1);
777 : 4764 : return scmv;
778 : : }
779 : 335050 : 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 : 5957 : 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 [ - + ]: 5957 : 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 : 5957 : jl_sym_t *rule = (jl_sym_t*)options;
795 [ + + + + : 5957 : 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 [ + + - + ]: 5957 : if (offset != 0 && rule == jl_all_sym) {
799 : 0 : jl_error("Parse `all`: offset not supported");
800 : : }
801 : :
802 : 5957 : jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
803 : 5957 : fl_context_t *fl_ctx = &ctx->fl;
804 : 5957 : value_t fl_text = cvalue_static_cstrn(fl_ctx, text, text_len);
805 : 5957 : fl_gc_handle(fl_ctx, &fl_text);
806 : 5957 : value_t fl_filename = cvalue_static_cstrn(fl_ctx, jl_string_data(filename),
807 : : jl_string_len(filename));
808 : 5957 : fl_gc_handle(fl_ctx, &fl_filename);
809 : : value_t fl_expr;
810 : 5957 : size_t offset1 = 0;
811 [ + + ]: 5957 : if (rule == jl_all_sym) {
812 : 1001 : value_t e = fl_applyn(fl_ctx, 3, symbol_value(symbol(fl_ctx, "jl-parse-all")),
813 : : fl_text, fl_filename, fixnum(lineno));
814 : 1001 : fl_expr = e;
815 [ - + ]: 1001 : offset1 = e == fl_ctx->FL_EOF ? text_len : 0;
816 : : }
817 : : else {
818 [ + + ]: 4956 : value_t greedy = rule == jl_statement_sym ? fl_ctx->T : fl_ctx->F;
819 : 4956 : 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 : 4956 : fl_expr = car_(p);
822 : 4956 : offset1 = tosize(fl_ctx, cdr_(p), "parse");
823 : : }
824 : 5957 : fl_free_gc_handles(fl_ctx, 2);
825 : :
826 : : // Convert to julia values
827 : 5957 : jl_value_t *expr = NULL, *end_offset = NULL;
828 : 5957 : JL_GC_PUSH2(&expr, &end_offset);
829 [ + + ]: 5957 : expr = fl_expr == fl_ctx->FL_EOF ? jl_nothing : scm_to_julia(fl_ctx, fl_expr, NULL);
830 : 5957 : end_offset = jl_box_long(offset1);
831 : 5957 : jl_ast_ctx_leave(ctx);
832 : 5957 : jl_value_t *result = (jl_value_t*)jl_svec2(expr, end_offset);
833 : 5957 : JL_GC_POP();
834 : 5957 : return result;
835 : : }
836 : :
837 : : // returns either an expression or a thunk
838 : 17229 : jl_value_t *jl_call_scm_on_ast(const char *funcname, jl_value_t *expr, jl_module_t *inmodule)
839 : : {
840 : 17229 : jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
841 : 17229 : fl_context_t *fl_ctx = &ctx->fl;
842 : 17229 : value_t arg = julia_to_scm(fl_ctx, expr);
843 : 17229 : value_t e = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, funcname)), arg);
844 : 17229 : jl_value_t *result = scm_to_julia(fl_ctx, e, inmodule);
845 : 17229 : JL_GC_PUSH1(&result);
846 : 17229 : jl_ast_ctx_leave(ctx);
847 : 17229 : JL_GC_POP();
848 : 17229 : return result;
849 : : }
850 : :
851 : 28650 : 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 : 28650 : jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
855 : 28650 : fl_context_t *fl_ctx = &ctx->fl;
856 : 28650 : value_t arg = julia_to_scm(fl_ctx, expr);
857 : 28650 : value_t e = fl_applyn(fl_ctx, 3, symbol_value(symbol(fl_ctx, funcname)), arg,
858 : 28650 : symbol(fl_ctx, file), fixnum(line));
859 : 28650 : jl_value_t *result = scm_to_julia(fl_ctx, e, inmodule);
860 : 28650 : JL_GC_PUSH1(&result);
861 : 28650 : jl_ast_ctx_leave(ctx);
862 : 28650 : JL_GC_POP();
863 : 28650 : return result;
864 : : }
865 : :
866 : : // syntax tree accessors
867 : :
868 : 5119090 : JL_DLLEXPORT jl_value_t *jl_copy_ast(jl_value_t *expr)
869 : : {
870 [ - + ]: 5119090 : if (!expr)
871 : 0 : return NULL;
872 [ - + ]: 5119090 : if (jl_is_code_info(expr)) {
873 : 0 : jl_code_info_t *new_ci = (jl_code_info_t *)expr;
874 : 0 : jl_array_t *new_code = NULL;
875 : 0 : JL_GC_PUSH2(&new_ci, &new_code);
876 : 0 : new_ci = jl_copy_code_info(new_ci);
877 : 0 : new_code = jl_array_copy(new_ci->code);
878 : 0 : size_t clen = jl_array_len(new_code);
879 [ # # ]: 0 : for (int i = 0; i < clen; ++i) {
880 : 0 : jl_array_ptr_set(new_code, i, jl_copy_ast(
881 : : jl_array_ptr_ref(new_code, i)
882 : : ));
883 : : }
884 : 0 : new_ci->code = new_code;
885 : 0 : jl_gc_wb(new_ci, new_code);
886 : 0 : new_ci->slotnames = jl_array_copy(new_ci->slotnames);
887 : 0 : jl_gc_wb(new_ci, new_ci->slotnames);
888 : 0 : new_ci->slotflags = jl_array_copy(new_ci->slotflags);
889 : 0 : jl_gc_wb(new_ci, new_ci->slotflags);
890 : 0 : new_ci->codelocs = (jl_value_t*)jl_array_copy((jl_array_t*)new_ci->codelocs);
891 : 0 : jl_gc_wb(new_ci, new_ci->codelocs);
892 : 0 : new_ci->linetable = (jl_value_t*)jl_array_copy((jl_array_t*)new_ci->linetable);
893 : 0 : jl_gc_wb(new_ci, new_ci->linetable);
894 : 0 : new_ci->ssaflags = jl_array_copy(new_ci->ssaflags);
895 : 0 : jl_gc_wb(new_ci, new_ci->ssaflags);
896 : :
897 [ # # ]: 0 : 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 [ # # ]: 0 : 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 : 0 : JL_GC_POP();
907 : 0 : return (jl_value_t*)new_ci;
908 : : }
909 [ + + ]: 5119090 : if (jl_is_expr(expr)) {
910 : 1960030 : jl_expr_t *e = (jl_expr_t*)expr;
911 : 1960030 : size_t i, l = jl_array_len(e->args);
912 : 1960030 : jl_expr_t *ne = jl_exprn(e->head, l);
913 : 1960030 : JL_GC_PUSH2(&ne, &expr);
914 [ + + ]: 6911580 : for (i = 0; i < l; i++) {
915 : 4951560 : jl_value_t *a = jl_exprarg(e, i);
916 : 4951560 : jl_exprargset(ne, i, jl_copy_ast(a));
917 : : }
918 : 1960030 : JL_GC_POP();
919 : 1960030 : return (jl_value_t*)ne;
920 : : }
921 [ - + ]: 3159060 : if (jl_is_phinode(expr)) {
922 : 0 : jl_array_t *edges = (jl_array_t*)jl_fieldref_noalloc(expr, 0);
923 : 0 : jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(expr, 1);
924 : 0 : JL_GC_PUSH2(&edges, &values);
925 : 0 : edges = jl_array_copy(edges);
926 : 0 : values = jl_array_copy(values);
927 : 0 : jl_value_t *ret = jl_new_struct(jl_phinode_type, edges, values);
928 : 0 : JL_GC_POP();
929 : 0 : return ret;
930 : : }
931 [ - + ]: 3159060 : 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 : 3159060 : return expr;
940 : : }
941 : :
942 : 2698 : JL_DLLEXPORT int jl_is_operator(char *sym)
943 : : {
944 : 2698 : jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
945 : 2698 : fl_context_t *fl_ctx = &ctx->fl;
946 : 2698 : int res = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "operator?")), symbol(fl_ctx, sym)) == fl_ctx->T;
947 : 2698 : jl_ast_ctx_leave(ctx);
948 : 2698 : return res;
949 : : }
950 : :
951 : 0 : JL_DLLEXPORT int jl_is_unary_operator(char *sym)
952 : : {
953 : 0 : jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
954 : 0 : fl_context_t *fl_ctx = &ctx->fl;
955 : 0 : int res = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "unary-op?")), symbol(fl_ctx, sym)) == fl_ctx->T;
956 : 0 : jl_ast_ctx_leave(ctx);
957 : 0 : 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 : 100 : JL_DLLEXPORT int jl_is_syntactic_operator(char *sym)
970 : : {
971 : 100 : jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
972 : 100 : fl_context_t *fl_ctx = &ctx->fl;
973 : 100 : int res = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "syntactic-op?")), symbol(fl_ctx, sym)) == fl_ctx->T;
974 : 100 : jl_ast_ctx_leave(ctx);
975 : 100 : return res;
976 : : }
977 : :
978 : 1938 : JL_DLLEXPORT int jl_operator_precedence(char *sym)
979 : : {
980 : 1938 : jl_ast_context_t *ctx = jl_ast_ctx_enter(NULL);
981 : 1938 : fl_context_t *fl_ctx = &ctx->fl;
982 : 1938 : int res = numval(fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "operator-precedence")), symbol(fl_ctx, sym)));
983 : 1938 : jl_ast_ctx_leave(ctx);
984 : 1938 : return res;
985 : : }
986 : :
987 : 195326 : int jl_has_meta(jl_array_t *body, jl_sym_t *sym) JL_NOTSAFEPOINT
988 : : {
989 : 195326 : size_t i, l = jl_array_len(body);
990 [ + + ]: 8253970 : for (i = 0; i < l; i++) {
991 : 8061550 : jl_expr_t *stmt = (jl_expr_t*)jl_array_ptr_ref(body, i);
992 [ + + + + ]: 8061550 : if (jl_is_expr((jl_value_t*)stmt) && stmt->head == jl_meta_sym) {
993 : 3055 : size_t i, l = jl_array_len(stmt->args);
994 [ + + ]: 3244 : for (i = 0; i < l; i++)
995 [ + + ]: 3101 : if (jl_array_ptr_ref(stmt->args, i) == (jl_value_t*)sym)
996 : 2912 : return 1;
997 : : }
998 : : }
999 : 192414 : return 0;
1000 : : }
1001 : :
1002 : 29164 : 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 : 29164 : jl_task_t *ct = jl_current_task;
1005 : : JL_TIMING(MACRO_INVOCATION);
1006 : 29164 : size_t nargs = jl_array_len(args) + 1;
1007 [ - + ]: 29164 : JL_NARGSV("macrocall", 3); // macro name, location, and module
1008 : : jl_value_t **margs;
1009 : 29164 : JL_GC_PUSHARGS(margs, nargs);
1010 : : int i;
1011 : 29164 : margs[0] = jl_array_ptr_ref(args, 0);
1012 : : // __source__ argument
1013 : 29164 : jl_value_t *lno = jl_array_ptr_ref(args, 1);
1014 : 29164 : margs[1] = lno;
1015 [ + + ]: 29164 : if (!jl_typeis(lno, jl_linenumbernode_type)) {
1016 : 6422 : margs[1] = jl_new_struct(jl_linenumbernode_type, jl_box_long(0), jl_nothing);
1017 : : }
1018 : 29164 : margs[2] = (jl_value_t*)inmodule;
1019 [ + + ]: 61141 : for (i = 3; i < nargs; i++)
1020 : 31977 : margs[i] = jl_array_ptr_ref(args, i - 1);
1021 : :
1022 : 29164 : size_t last_age = ct->world_age;
1023 : 29164 : ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
1024 [ - + ]: 29164 : if (ct->world_age > world)
1025 : 0 : ct->world_age = world;
1026 : : jl_value_t *result;
1027 [ + - + + ]: 58328 : JL_TRY {
1028 : 29164 : margs[0] = jl_toplevel_eval(*ctx, margs[0]);
1029 : 29164 : jl_method_instance_t *mfunc = jl_method_lookup(margs, nargs, world);
1030 : : JL_GC_PROMISE_ROOTED(mfunc);
1031 [ - + ]: 29164 : if (mfunc == NULL) {
1032 : 0 : jl_method_error(margs[0], &margs[1], nargs, world);
1033 : : // unreachable
1034 : : }
1035 : 29164 : *ctx = mfunc->def.method->module;
1036 : 29164 : result = jl_invoke(margs[0], &margs[1], nargs - 1, mfunc);
1037 : : }
1038 [ # # ]: 0 : JL_CATCH {
1039 [ # # # # ]: 0 : if ((jl_loaderror_type == NULL) || !throw_load_error) {
1040 : 0 : jl_rethrow();
1041 : : }
1042 : : else {
1043 : 0 : jl_value_t *lno = margs[1];
1044 : 0 : jl_value_t *file = jl_fieldref(lno, 1);
1045 [ # # ]: 0 : if (jl_is_symbol(file))
1046 : 0 : 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 : 0 : margs[1] = jl_fieldref(lno, 0); // extract and allocate line number
1050 : 0 : jl_rethrow_other(jl_new_struct(jl_loaderror_type, margs[0], margs[1],
1051 : : jl_current_exception()));
1052 : : }
1053 : : }
1054 : 29164 : ct->world_age = last_age;
1055 : 29164 : JL_GC_POP();
1056 : 29164 : return result;
1057 : : }
1058 : :
1059 : 3271540 : 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 [ + - + + ]: 3271540 : if (!expr || !jl_is_expr(expr))
1062 : 1987320 : return expr;
1063 : 1284220 : jl_expr_t *e = (jl_expr_t*)expr;
1064 [ + - ]: 1284220 : if (e->head == jl_inert_sym ||
1065 [ + + ]: 1284220 : e->head == jl_module_sym ||
1066 : : //e->head == jl_toplevel_sym || // TODO: enable this once julia-expand-macroscope is fixed / removed
1067 [ + + ]: 1284000 : e->head == jl_meta_sym) {
1068 : 7939 : return expr;
1069 : : }
1070 [ + + + - ]: 1276280 : if (e->head == jl_quote_sym && jl_expr_nargs(e) == 1) {
1071 : 10213 : expr = jl_call_scm_on_ast("julia-bq-macro", jl_exprarg(e, 0), inmodule);
1072 : 10213 : JL_GC_PUSH1(&expr);
1073 : 10213 : expr = jl_expand_macros(expr, inmodule, macroctx, onelevel, world, throw_load_error);
1074 : 10213 : JL_GC_POP();
1075 : 10213 : return expr;
1076 : : }
1077 [ + + + - ]: 1266060 : if (e->head == jl_hygienicscope_sym && jl_expr_nargs(e) == 2) {
1078 : : struct macroctx_stack newctx;
1079 : 6516 : newctx.m = (jl_module_t*)jl_exprarg(e, 1);
1080 [ - + ]: 6516 : JL_TYPECHK(hygienic-scope, module, (jl_value_t*)newctx.m);
1081 : 6516 : newctx.parent = macroctx;
1082 : 6516 : jl_value_t *a = jl_exprarg(e, 0);
1083 : 6516 : jl_value_t *a2 = jl_expand_macros(a, inmodule, &newctx, onelevel, world, throw_load_error);
1084 [ - + ]: 6516 : if (a != a2)
1085 : 0 : jl_array_ptr_set(e->args, 0, a2);
1086 : 6516 : return expr;
1087 : : }
1088 [ + + ]: 1259550 : if (e->head == jl_macrocall_sym) {
1089 : : struct macroctx_stack newctx;
1090 [ + + ]: 29164 : newctx.m = macroctx ? macroctx->m : inmodule;
1091 : 29164 : newctx.parent = macroctx;
1092 : 29164 : jl_value_t *result = jl_invoke_julia_macro(e->args, inmodule, &newctx.m, world, throw_load_error);
1093 : 29164 : jl_value_t *wrap = NULL;
1094 : 29164 : JL_GC_PUSH3(&result, &wrap, &newctx.m);
1095 : : // copy and wrap the result in `(hygienic-scope ,result ,newctx)
1096 [ + + + + ]: 29164 : if (jl_is_expr(result) && ((jl_expr_t*)result)->head == jl_escape_sym)
1097 : 12043 : result = jl_exprarg(result, 0);
1098 : : else
1099 : 17121 : wrap = (jl_value_t*)jl_exprn(jl_hygienicscope_sym, 2);
1100 : 29164 : result = jl_copy_ast(result);
1101 [ + - ]: 29164 : if (!onelevel)
1102 [ + + ]: 29164 : result = jl_expand_macros(result, inmodule, wrap ? &newctx : macroctx, onelevel, world, throw_load_error);
1103 [ + + ]: 29164 : if (wrap) {
1104 : 17121 : jl_exprargset(wrap, 0, result);
1105 : 17121 : jl_exprargset(wrap, 1, newctx.m);
1106 : 17121 : result = wrap;
1107 : : }
1108 : 29164 : JL_GC_POP();
1109 : 29164 : return result;
1110 : : }
1111 [ + + + - : 1230380 : if (e->head == jl_do_sym && jl_expr_nargs(e) == 2 && jl_is_expr(jl_exprarg(e, 0)) &&
+ - ]
1112 [ - + ]: 1024 : ((jl_expr_t*)jl_exprarg(e, 0))->head == jl_macrocall_sym) {
1113 : 0 : jl_expr_t *mc = (jl_expr_t*)jl_exprarg(e, 0);
1114 : 0 : size_t nm = jl_expr_nargs(mc);
1115 : 0 : jl_expr_t *mc2 = jl_exprn(jl_macrocall_sym, nm+1);
1116 : 0 : JL_GC_PUSH1(&mc2);
1117 : 0 : jl_exprargset(mc2, 0, jl_exprarg(mc, 0)); // macro name
1118 : 0 : jl_exprargset(mc2, 1, jl_exprarg(mc, 1)); // location
1119 : 0 : jl_exprargset(mc2, 2, jl_exprarg(e, 1)); // function argument
1120 : : size_t j;
1121 [ # # ]: 0 : for (j = 2; j < nm; j++) {
1122 : 0 : jl_exprargset(mc2, j+1, jl_exprarg(mc, j));
1123 : : }
1124 : 0 : jl_value_t *ret = jl_expand_macros((jl_value_t*)mc2, inmodule, macroctx, onelevel, world, throw_load_error);
1125 : 0 : JL_GC_POP();
1126 : 0 : return ret;
1127 : : }
1128 [ + + + - ]: 1230380 : if (e->head == jl_escape_sym && macroctx) {
1129 : 36422 : macroctx = macroctx->parent;
1130 : : }
1131 : :
1132 : : size_t i;
1133 [ + + ]: 4372460 : for (i = 0; i < jl_array_len(e->args); i++) {
1134 : 3142070 : jl_value_t *a = jl_array_ptr_ref(e->args, i);
1135 : 3142070 : jl_value_t *a2 = jl_expand_macros(a, inmodule, macroctx, onelevel, world, throw_load_error);
1136 [ + + ]: 3142070 : if (a != a2)
1137 : 29200 : jl_array_ptr_set(e->args, i, a2);
1138 : : }
1139 : 1230380 : return expr;
1140 : : }
1141 : :
1142 : 6796 : JL_DLLEXPORT jl_value_t *jl_macroexpand(jl_value_t *expr, jl_module_t *inmodule)
1143 : : {
1144 : : JL_TIMING(LOWERING);
1145 : 6796 : JL_GC_PUSH1(&expr);
1146 : 6796 : expr = jl_copy_ast(expr);
1147 : 6796 : expr = jl_expand_macros(expr, inmodule, NULL, 0, jl_atomic_load_acquire(&jl_world_counter), 0);
1148 : 6796 : expr = jl_call_scm_on_ast("jl-expand-macroscope", expr, inmodule);
1149 : 6796 : JL_GC_POP();
1150 : 6796 : return expr;
1151 : : }
1152 : :
1153 : 0 : JL_DLLEXPORT jl_value_t *jl_macroexpand1(jl_value_t *expr, jl_module_t *inmodule)
1154 : : {
1155 : : JL_TIMING(LOWERING);
1156 : 0 : JL_GC_PUSH1(&expr);
1157 : 0 : expr = jl_copy_ast(expr);
1158 : 0 : expr = jl_expand_macros(expr, inmodule, NULL, 1, jl_atomic_load_acquire(&jl_world_counter), 0);
1159 : 0 : expr = jl_call_scm_on_ast("jl-expand-macroscope", expr, inmodule);
1160 : 0 : JL_GC_POP();
1161 : 0 : return expr;
1162 : : }
1163 : :
1164 : : // Lower an expression tree into Julia's intermediate-representation.
1165 : 1139 : JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr, jl_module_t *inmodule)
1166 : : {
1167 : 1139 : return jl_expand_with_loc(expr, inmodule, "none", 0);
1168 : : }
1169 : :
1170 : : // Lowering, with starting program location specified
1171 : 1139 : 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 : 1139 : return jl_expand_in_world(expr, inmodule, file, line, ~(size_t)0);
1175 : : }
1176 : :
1177 : : // Lowering, with starting program location and worldage specified
1178 : 1139 : 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 : 1139 : JL_GC_PUSH1(&expr);
1183 : 1139 : expr = jl_copy_ast(expr);
1184 : 1139 : expr = jl_expand_macros(expr, inmodule, NULL, 0, world, 1);
1185 : 1139 : expr = jl_call_scm_on_ast_and_loc("jl-expand-to-thunk", expr, inmodule, file, line);
1186 : 1139 : JL_GC_POP();
1187 : 1139 : return expr;
1188 : : }
1189 : :
1190 : : // Same as the above, but printing warnings when applicable
1191 : 48128 : 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 : 48128 : jl_array_t *kwargs = NULL;
1196 : 48128 : JL_GC_PUSH2(&expr, &kwargs);
1197 : 48128 : expr = jl_copy_ast(expr);
1198 : 48128 : expr = jl_expand_macros(expr, inmodule, NULL, 0, ~(size_t)0, 1);
1199 : 48128 : jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
1200 : 48128 : fl_context_t *fl_ctx = &ctx->fl;
1201 : 48128 : value_t arg = julia_to_scm(fl_ctx, expr);
1202 : 48128 : value_t e = fl_applyn(fl_ctx, 4, symbol_value(symbol(fl_ctx, "jl-expand-to-thunk-warn")), arg,
1203 : 48128 : symbol(fl_ctx, file), fixnum(line), fl_ctx->F);
1204 : 48128 : expr = scm_to_julia(fl_ctx, e, inmodule);
1205 : 48128 : jl_ast_ctx_leave(ctx);
1206 : 48128 : jl_sym_t *warn_sym = jl_symbol("warn");
1207 [ + + - + ]: 48128 : 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 : 48128 : JL_GC_POP();
1235 : 48128 : return expr;
1236 : : }
1237 : :
1238 : : // expand in a context where the expression value is unused
1239 : 27511 : 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 : 27511 : JL_GC_PUSH1(&expr);
1244 : 27511 : expr = jl_copy_ast(expr);
1245 : 27511 : expr = jl_expand_macros(expr, inmodule, NULL, 0, ~(size_t)0, 1);
1246 : 27511 : expr = jl_call_scm_on_ast_and_loc("jl-expand-to-thunk-stmt", expr, inmodule, file, line);
1247 : 27511 : JL_GC_POP();
1248 : 27511 : 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 : 411 : 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 : 411 : jl_value_t *core_parse = NULL;
1267 [ + - ]: 411 : if (jl_core_module) {
1268 : 411 : core_parse = jl_get_global(jl_core_module, jl_symbol("_parse"));
1269 : : }
1270 [ + + + + ]: 411 : 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 : 346 : JL_GC_PUSHARGS(args, 6);
1277 : 346 : args[0] = core_parse;
1278 : 346 : args[1] = (jl_value_t*)jl_alloc_svec(2);
1279 : 346 : jl_svecset(args[1], 0, jl_box_uint8pointer((uint8_t*)text));
1280 : 346 : jl_svecset(args[1], 1, jl_box_long(text_len));
1281 : 346 : args[2] = filename;
1282 : 346 : args[3] = jl_box_ulong(lineno);
1283 : 346 : args[4] = jl_box_ulong(offset);
1284 : 346 : args[5] = options;
1285 : 346 : jl_task_t *ct = jl_current_task;
1286 : 346 : size_t last_age = ct->world_age;
1287 : 346 : ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
1288 : 346 : jl_value_t *result = jl_apply(args, 6);
1289 : 346 : ct->world_age = last_age;
1290 : 346 : args[0] = result; // root during error checks below
1291 [ - + ]: 346 : JL_TYPECHK(parse, simplevector, result);
1292 [ - + ]: 346 : if (jl_svec_len(result) != 2)
1293 : 0 : jl_error("Result from parser should be `svec(a::Expr, b::Int)`");
1294 [ - + ]: 346 : JL_TYPECHK(parse, expr, jl_svecref(result, 0));
1295 [ - + ]: 346 : JL_TYPECHK(parse, long, jl_svecref(result, 1));
1296 : 346 : JL_GC_POP();
1297 : 346 : 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
|