// load toplevel expressions, from (file ...) void jl_load_file_expr(char *fname, jl_value_t *ast) { jl_array_t *b = ((jl_expr_t*)ast)->args; size_t i; volatile size_t lineno=0; if (((jl_expr_t*)ast)->head == jl_continue_sym) { jl_errorf("syntax error: %s", jl_string_data(jl_exprarg(ast,0))); } JL_TRY { jl_register_toplevel_eh(); // handle syntax error if (((jl_expr_t*)ast)->head == error_sym) { jl_interpret_toplevel_expr(ast); } for(i=0; i < b->length; i++) { // process toplevel form jl_value_t *form = jl_cellref(b, i); if (jl_is_linenode(form)) { lineno = jl_linenode_line(form); } else { (void)jl_toplevel_eval_flex(form, 0, &lineno); } } } JL_CATCH { jl_value_t *fn=NULL, *ln=NULL; JL_GC_PUSH(&fn, &ln); fn = jl_pchar_to_string(fname, strlen(fname)); ln = jl_box_long(lineno); jl_raise(jl_new_struct(jl_loaderror_type, fn, ln, jl_exception_in_transit)); } }
jl_value_t *jl_eval_module_expr(jl_expr_t *ex, int *plineno) { assert(ex->head == module_sym); jl_module_t *last_module = jl_current_module; jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 0); if (!jl_is_symbol(name)) { jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name); } if (name == jl_current_module->name) { jl_errorf("module name %s conflicts with enclosing module", name->name); } jl_binding_t *b = jl_get_binding_wr(jl_current_module, name); jl_declare_constant(b); if (b->value != NULL) { JL_PRINTF(JL_STDERR, "Warning: redefinition of module %s ignored\n", name->name); return jl_nothing; } jl_module_t *newm = jl_new_module(name); b->value = (jl_value_t*)newm; if (jl_current_module == jl_core_module && name == jl_symbol("Base")) { // pick up Base module during bootstrap, and stay within it // after loading. jl_base_module = last_module = newm; } JL_GC_PUSH(&last_module); jl_current_module = newm; jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 1))->args; JL_TRY { for(int i=0; i < exprs->length; i++) { // process toplevel form jl_value_t *form = jl_cellref(exprs, i); if (jl_is_linenode(form)) { if (plineno) *plineno = jl_linenode_line(form); } else { (void)jl_toplevel_eval_flex(form, 0, plineno); } } } JL_CATCH { JL_GC_POP(); jl_current_module = last_module; jl_raise(jl_exception_in_transit); } JL_GC_POP(); jl_current_module = last_module; return jl_nothing; }
// load toplevel expressions, from (file ...) void jl_load_file_expr(char *fname, jl_value_t *ast) { jl_array_t *b = ((jl_expr_t*)ast)->args; size_t i; volatile size_t lineno=0; if (((jl_expr_t*)ast)->head == jl_continue_sym) { jl_errorf("syntax error: %s", jl_string_data(jl_exprarg(ast,0))); } char oldcwd[512]; char newcwd[512]; get_cwd(oldcwd, sizeof(oldcwd)); char *sep = strrchr(fname, PATHSEP); if (sep) { size_t n = (sep - fname)+1; if (n > sizeof(newcwd)-1) n = sizeof(newcwd)-1; strncpy(newcwd, fname, n); newcwd[n] = '\0'; set_cwd(newcwd); } JL_TRY { jl_register_toplevel_eh(); // handle syntax error if (((jl_expr_t*)ast)->head == error_sym) { jl_interpret_toplevel_expr(ast); } for(i=0; i < b->length; i++) { // process toplevel form jl_value_t *form = jl_cellref(b, i); if (jl_is_linenode(form)) { lineno = jl_linenode_line(form); } else { (void)jl_toplevel_eval_flex(form, 0, &lineno); } } } JL_CATCH { if (sep) set_cwd(oldcwd); jl_value_t *fn=NULL, *ln=NULL; JL_GC_PUSH(&fn, &ln); fn = jl_pchar_to_string(fname, strlen(fname)); ln = jl_box_long(lineno); jl_raise(jl_new_struct(jl_loaderror_type, fn, ln, jl_exception_in_transit)); } if (sep) set_cwd(oldcwd); }
JL_DLLEXPORT void jl_method_init_properties(jl_method_t *m) { jl_lambda_info_t *li = m->lambda_template; jl_value_t *body1 = skip_meta((jl_array_t*)li->code); if (jl_is_linenode(body1)) { m->line = jl_linenode_line(body1); } else if (jl_is_expr(body1) && ((jl_expr_t*)body1)->head == line_sym) { m->file = (jl_sym_t*)jl_exprarg(body1, 1); m->line = jl_unbox_long(jl_exprarg(body1, 0)); } int i; uint8_t called=0; for(i=1; i < li->nargs && i <= 8; i++) { jl_value_t *ai = jl_array_ptr_ref(li->slotnames,i); if (ai == (jl_value_t*)unused_sym) continue; if (jl_array_uint8_ref(li->slotflags,i)&64) called |= (1<<(i-1)); } m->called = called; }
jl_value_t *jl_eval_module_expr(jl_expr_t *ex, int *plineno) { assert(ex->head == module_sym); jl_module_t *last_module = jl_current_module; jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 0); if (!jl_is_symbol(name)) { jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name); } jl_module_t *parent_module; if (jl_current_module == jl_core_module || jl_current_module == jl_main_module) { parent_module = jl_root_module; } else { parent_module = jl_current_module; } jl_binding_t *b = jl_get_binding_wr(parent_module, name); jl_declare_constant(b); if (b->value != NULL) { JL_PRINTF(JL_STDERR, "Warning: replacing module %s\n", name->name); } jl_module_t *newm = jl_new_module(name); newm->parent = (jl_value_t*)parent_module; b->value = (jl_value_t*)newm; if (parent_module == jl_root_module && name == jl_symbol("Base") && jl_base_module == NULL) { // pick up Base module during bootstrap jl_base_module = newm; } JL_GC_PUSH(&last_module); jl_current_module = newm; jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 1))->args; JL_TRY { for(int i=0; i < exprs->length; i++) { // process toplevel form jl_value_t *form = jl_cellref(exprs, i); if (jl_is_linenode(form)) { if (plineno) *plineno = jl_linenode_line(form); } else { (void)jl_toplevel_eval_flex(form, 1, plineno); } } } JL_CATCH { JL_GC_POP(); jl_current_module = last_module; jl_raise(jl_exception_in_transit); } JL_GC_POP(); jl_current_module = last_module; size_t i; void **table = newm->bindings.table; for(i=1; i < newm->bindings.size; i+=2) { if (table[i] != HT_NOTFOUND) { jl_binding_t *b = (jl_binding_t*)table[i]; // remove non-exported macros if (b->name->name[0]=='@' && !b->exportp) b->value = NULL; // error for unassigned exports /* if (b->exportp && b->owner==newm && b->value==NULL) jl_errorf("identifier %s exported from %s is not initialized", b->name->name, newm->name->name); */ } } return jl_nothing; }
static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl, size_t ngensym) { if (jl_is_symbol(e)) { jl_value_t *v; size_t i; for(i=0; i < nl; i++) { if (locals[i*2] == e) { v = locals[i*2+1]; break; } } if (i >= nl) { v = jl_get_global(jl_current_module, (jl_sym_t*)e); } if (v == NULL) { jl_undefined_var_error((jl_sym_t*)e); } return v; } if (jl_is_symbolnode(e)) { return eval((jl_value_t*)jl_symbolnode_sym(e), locals, nl, ngensym); } if (jl_is_gensym(e)) { ssize_t genid = ((jl_gensym_t*)e)->id; if (genid >= ngensym || genid < 0) jl_error("access to invalid GenSym location"); else return locals[nl*2 + genid]; } if (jl_is_quotenode(e)) { return jl_fieldref(e,0); } if (jl_is_topnode(e)) { jl_sym_t *s = (jl_sym_t*)jl_fieldref(e,0); jl_value_t *v = jl_get_global(jl_base_relative_to(jl_current_module),s); if (v == NULL) jl_undefined_var_error(s); return v; } if (!jl_is_expr(e)) { if (jl_is_globalref(e)) { jl_value_t *gfargs[2] = {(jl_value_t*)jl_globalref_mod(e), (jl_value_t*)jl_globalref_name(e)}; return jl_f_get_field(NULL, gfargs, 2); } if (jl_is_lambda_info(e)) { jl_lambda_info_t *li = (jl_lambda_info_t*)e; if (jl_boot_file_loaded && li->ast && jl_is_expr(li->ast)) { li->ast = jl_compress_ast(li, li->ast); jl_gc_wb(li, li->ast); } return (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_emptysvec, li); } if (jl_is_linenode(e)) { jl_lineno = jl_linenode_line(e); } if (jl_is_newvarnode(e)) { jl_value_t *var = jl_fieldref(e,0); assert(!jl_is_gensym(var)); assert(jl_is_symbol(var)); for(size_t i=0; i < nl; i++) { if (locals[i*2] == var) { locals[i*2+1] = NULL; break; } } return (jl_value_t*)jl_nothing; } return e; } jl_expr_t *ex = (jl_expr_t*)e; jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); size_t nargs = jl_array_len(ex->args); if (ex->head == call_sym) { if (jl_is_lambda_info(args[0])) { // directly calling an inner function ("let") jl_lambda_info_t *li = (jl_lambda_info_t*)args[0]; if (jl_is_expr(li->ast) && !jl_lam_vars_captured((jl_expr_t*)li->ast) && !jl_has_intrinsics((jl_expr_t*)li->ast, (jl_expr_t*)li->ast, jl_current_module)) { size_t na = nargs-1; if (na == 0) return jl_interpret_toplevel_thunk(li); jl_array_t *formals = jl_lam_args((jl_expr_t*)li->ast); size_t nreq = jl_array_len(formals); if (nreq==0 || !jl_is_rest_arg(jl_cellref(formals,nreq-1))) { jl_value_t **ar; JL_GC_PUSHARGS(ar, na*2); for(int i=0; i < na; i++) { ar[i*2+1] = eval(args[i+1], locals, nl, ngensym); jl_gc_wb(ex->args, ar[i*2+1]); } if (na != nreq) { jl_error("wrong number of arguments"); } for(int i=0; i < na; i++) { jl_value_t *v = jl_cellref(formals, i); ar[i*2] = (jl_is_gensym(v)) ? v : (jl_value_t*)jl_decl_var(v); } jl_value_t *ret = jl_interpret_toplevel_thunk_with(li, ar, na); JL_GC_POP(); return ret; } } } jl_function_t *f = (jl_function_t*)eval(args[0], locals, nl, ngensym); if (jl_is_func(f)) return do_call(f, &args[1], nargs-1, NULL, locals, nl, ngensym); else return do_call(jl_module_call_func(jl_current_module), args, nargs, (jl_value_t*)f, locals, nl, ngensym); } else if (ex->head == assign_sym) { jl_value_t *sym = args[0]; jl_value_t *rhs = eval(args[1], locals, nl, ngensym); if (jl_is_gensym(sym)) { ssize_t genid = ((jl_gensym_t*)sym)->id; if (genid >= ngensym || genid < 0) jl_error("assignment to invalid GenSym location"); locals[nl*2 + genid] = rhs; return rhs; } if (jl_is_symbol(sym)) { size_t i; for (i=0; i < nl; i++) { if (locals[i*2] == sym) { locals[i*2+1] = rhs; return rhs; } } } jl_module_t *m = jl_current_module; if (jl_is_globalref(sym)) { m = jl_globalref_mod(sym); sym = (jl_value_t*)jl_globalref_name(sym); } assert(jl_is_symbol(sym)); JL_GC_PUSH1(&rhs); jl_binding_t *b = jl_get_binding_wr(m, (jl_sym_t*)sym); jl_checked_assignment(b, rhs); JL_GC_POP(); return rhs; } else if (ex->head == new_sym) { jl_value_t *thetype = eval(args[0], locals, nl, ngensym); jl_value_t *v=NULL; JL_GC_PUSH2(&thetype, &v); assert(jl_is_structtype(thetype)); v = jl_new_struct_uninit((jl_datatype_t*)thetype); for(size_t i=1; i < nargs; i++) { jl_set_nth_field(v, i-1, eval(args[i], locals, nl, ngensym)); } JL_GC_POP(); return v; } else if (ex->head == null_sym) { return (jl_value_t*)jl_nothing; } else if (ex->head == body_sym) { return eval_body(ex->args, locals, nl, ngensym, 0, 0); } else if (ex->head == exc_sym) { return jl_exception_in_transit; } else if (ex->head == static_typeof_sym) { return (jl_value_t*)jl_any_type; } else if (ex->head == method_sym) { jl_sym_t *fname = (jl_sym_t*)args[0]; jl_value_t **bp=NULL; jl_value_t *bp_owner=NULL; jl_binding_t *b=NULL; jl_value_t *gf=NULL; int kw=0; if (jl_is_expr(fname) || jl_is_globalref(fname)) { if (jl_is_expr(fname) && ((jl_expr_t*)fname)->head == kw_sym) { kw = 1; fname = (jl_sym_t*)jl_exprarg(fname, 0); } gf = eval((jl_value_t*)fname, locals, nl, ngensym); if (jl_is_expr(fname)) fname = (jl_sym_t*)jl_fieldref(jl_exprarg(fname, 2), 0); bp = &gf; assert(jl_is_symbol(fname)); } else { for (size_t i=0; i < nl; i++) { if (locals[i*2] == (jl_value_t*)fname) { bp = &locals[i*2+1]; break; } } if (bp == NULL) { b = jl_get_binding_for_method_def(jl_current_module, fname); bp = &b->value; bp_owner = (jl_value_t*)jl_current_module; } } if (jl_expr_nargs(ex) == 1) return jl_generic_function_def(fname, bp, bp_owner, b); jl_value_t *atypes=NULL, *meth=NULL; JL_GC_PUSH2(&atypes, &meth); atypes = eval(args[1], locals, nl, ngensym); if (jl_is_lambda_info(args[2])) { jl_check_static_parameter_conflicts((jl_lambda_info_t*)args[2], (jl_svec_t*)jl_svecref(atypes,1), fname); } meth = eval(args[2], locals, nl, ngensym); jl_method_def(fname, bp, bp_owner, b, (jl_svec_t*)atypes, (jl_function_t*)meth, args[3], NULL, kw); JL_GC_POP(); return *bp; } else if (ex->head == copyast_sym) { return jl_copy_ast(eval(args[0], locals, nl, ngensym)); } else if (ex->head == const_sym) { jl_value_t *sym = args[0]; assert(jl_is_symbol(sym)); for (size_t i=0; i < nl; i++) { if (locals[i*2] == sym) { return (jl_value_t*)jl_nothing; } } jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)sym); jl_declare_constant(b); return (jl_value_t*)jl_nothing; } else if (ex->head == global_sym) { // create uninitialized mutable binding for "global x" decl // TODO: handle type decls for (size_t i=0; i < jl_array_len(ex->args); i++) { assert(jl_is_symbol(args[i])); jl_get_binding_wr(jl_current_module, (jl_sym_t*)args[i]); } return (jl_value_t*)jl_nothing; } else if (ex->head == abstracttype_sym) { jl_value_t *name = args[0]; jl_value_t *para = eval(args[1], locals, nl, ngensym); jl_value_t *super = NULL; jl_value_t *temp = NULL; jl_datatype_t *dt = NULL; JL_GC_PUSH4(¶, &super, &temp, &dt); assert(jl_is_svec(para)); assert(jl_is_symbol(name)); dt = jl_new_abstracttype(name, jl_any_type, (jl_svec_t*)para); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); temp = b->value; check_can_assign_type(b); b->value = (jl_value_t*)dt; jl_gc_wb_binding(b, dt); super = eval(args[2], locals, nl, ngensym); jl_set_datatype_super(dt, super); b->value = temp; if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) { jl_checked_assignment(b, (jl_value_t*)dt); } JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == bitstype_sym) { jl_value_t *name = args[0]; jl_value_t *super = NULL, *para = NULL, *vnb = NULL, *temp = NULL; jl_datatype_t *dt = NULL; JL_GC_PUSH4(¶, &super, &temp, &dt); assert(jl_is_symbol(name)); para = eval(args[1], locals, nl, ngensym); assert(jl_is_svec(para)); vnb = eval(args[2], locals, nl, ngensym); if (!jl_is_long(vnb)) jl_errorf("invalid declaration of bits type %s", ((jl_sym_t*)name)->name); ssize_t nb = jl_unbox_long(vnb); if (nb < 1 || nb>=(1<<23) || (nb&7) != 0) jl_errorf("invalid number of bits in type %s", ((jl_sym_t*)name)->name); dt = jl_new_bitstype(name, jl_any_type, (jl_svec_t*)para, nb); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); temp = b->value; check_can_assign_type(b); b->value = (jl_value_t*)dt; jl_gc_wb_binding(b, dt); super = eval(args[3], locals, nl, ngensym); jl_set_datatype_super(dt, super); b->value = temp; if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) { jl_checked_assignment(b, (jl_value_t*)dt); } JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == compositetype_sym) { jl_value_t *name = args[0]; assert(jl_is_symbol(name)); jl_value_t *para = eval(args[1], locals, nl, ngensym); assert(jl_is_svec(para)); jl_value_t *temp = NULL; jl_value_t *super = NULL; jl_datatype_t *dt = NULL; JL_GC_PUSH4(¶, &super, &temp, &dt); temp = eval(args[2], locals, nl, ngensym); // field names dt = jl_new_datatype((jl_sym_t*)name, jl_any_type, (jl_svec_t*)para, (jl_svec_t*)temp, NULL, 0, args[5]==jl_true ? 1 : 0, jl_unbox_long(args[6])); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); temp = b->value; // save old value // temporarily assign so binding is available for field types check_can_assign_type(b); b->value = (jl_value_t*)dt; jl_gc_wb_binding(b,dt); JL_TRY { // operations that can fail inside_typedef = 1; dt->types = (jl_svec_t*)eval(args[4], locals, nl, ngensym); jl_gc_wb(dt, dt->types); inside_typedef = 0; for(size_t i=0; i < jl_svec_len(dt->types); i++) { jl_value_t *elt = jl_svecref(dt->types, i); if (!jl_is_type(elt) && !jl_is_typevar(elt)) jl_type_error_rt(dt->name->name->name, "type definition", (jl_value_t*)jl_type_type, elt); } super = eval(args[3], locals, nl, ngensym); jl_set_datatype_super(dt, super); } JL_CATCH { b->value = temp; jl_rethrow(); } for(size_t i=0; i < jl_svec_len(para); i++) { ((jl_tvar_t*)jl_svecref(para,i))->bound = 0; } jl_compute_field_offsets(dt); if (para == (jl_value_t*)jl_emptysvec && jl_is_datatype_singleton(dt)) { dt->instance = newstruct(dt); jl_gc_wb(dt, dt->instance); } b->value = temp; if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) { jl_checked_assignment(b, (jl_value_t*)dt); } else { // TODO: remove all old ctors and set temp->name->ctor_factory = dt->name->ctor_factory } JL_GC_POP(); return (jl_value_t*)jl_nothing; }
// parse and eval a whole file, possibly reading from a string (`content`) jl_value_t *jl_parse_eval_all(const char *fname, const char *content, size_t contentlen, jl_module_t *inmodule) { jl_ptls_t ptls = jl_get_ptls_states(); if (ptls->in_pure_callback) jl_error("cannot use include inside a generated function"); jl_ast_context_t *ctx = jl_ast_ctx_enter(); fl_context_t *fl_ctx = &ctx->fl; value_t f, ast, expression; size_t len = strlen(fname); f = cvalue_static_cstrn(fl_ctx, fname, len); fl_gc_handle(fl_ctx, &f); if (content != NULL) { JL_TIMING(PARSING); value_t t = cvalue_static_cstrn(fl_ctx, content, contentlen); fl_gc_handle(fl_ctx, &t); ast = fl_applyn(fl_ctx, 2, symbol_value(symbol(fl_ctx, "jl-parse-string-stream")), t, f); fl_free_gc_handles(fl_ctx, 1); } else { JL_TIMING(PARSING); assert(memchr(fname, 0, len) == NULL); // was checked already in jl_load ast = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-parse-file")), f); } fl_free_gc_handles(fl_ctx, 1); if (ast == fl_ctx->F) { jl_ast_ctx_leave(ctx); jl_errorf("could not open file %s", fname); } fl_gc_handle(fl_ctx, &ast); fl_gc_handle(fl_ctx, &expression); int last_lineno = jl_lineno; const char *last_filename = jl_filename; size_t last_age = jl_get_ptls_states()->world_age; jl_lineno = 0; jl_filename = fname; jl_module_t *old_module = ctx->module; ctx->module = inmodule; jl_value_t *form = NULL; jl_value_t *result = jl_nothing; int err = 0; JL_GC_PUSH2(&form, &result); JL_TRY { assert(iscons(ast) && car_(ast) == symbol(fl_ctx, "toplevel")); ast = cdr_(ast); while (iscons(ast)) { expression = car_(ast); { JL_TIMING(LOWERING); if (fl_ctx->T == fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "contains-macrocall")), expression)) { form = scm_to_julia(fl_ctx, expression, inmodule); form = jl_expand_macros(form, inmodule, NULL, 0); expression = julia_to_scm(fl_ctx, form); } // expand non-final expressions in statement position (value unused) expression = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, iscons(cdr_(ast)) ? "jl-expand-to-thunk-stmt" : "jl-expand-to-thunk")), expression); } jl_get_ptls_states()->world_age = jl_world_counter; form = scm_to_julia(fl_ctx, expression, inmodule); JL_SIGATOMIC_END(); jl_get_ptls_states()->world_age = jl_world_counter; if (jl_is_linenode(form)) jl_lineno = jl_linenode_line(form); else result = jl_toplevel_eval_flex(inmodule, form, 1, 1); JL_SIGATOMIC_BEGIN(); ast = cdr_(ast); } } JL_CATCH { form = jl_pchar_to_string(fname, len); result = jl_box_long(jl_lineno); err = 1; } jl_get_ptls_states()->world_age = last_age; jl_lineno = last_lineno; jl_filename = last_filename; fl_free_gc_handles(fl_ctx, 2); ctx->module = old_module; jl_ast_ctx_leave(ctx); if (err) { if (jl_loaderror_type == NULL) jl_rethrow(); else jl_rethrow_other(jl_new_struct(jl_loaderror_type, form, result, ptls->exception_in_transit)); } JL_GC_POP(); return result; }
static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl) { if (jl_is_symbol(e)) { jl_value_t *v; size_t i; for(i=0; i < nl; i++) { if (locals[i*2] == e) { v = locals[i*2+1]; break; } } if (i >= nl) { v = jl_get_global(jl_current_module, (jl_sym_t*)e); } if (v == NULL) { jl_errorf("%s not defined", ((jl_sym_t*)e)->name); } return v; } if (jl_is_symbolnode(e)) { return eval((jl_value_t*)jl_symbolnode_sym(e), locals, nl); } if (jl_is_quotenode(e)) { return jl_fieldref(e,0); } if (jl_is_topnode(e)) { jl_sym_t *s = (jl_sym_t*)jl_fieldref(e,0); jl_value_t *v = jl_get_global(jl_base_relative_to(jl_current_module),s); if (v == NULL) jl_errorf("%s not defined", s->name); return v; } if (!jl_is_expr(e)) { if (jl_is_getfieldnode(e)) { jl_value_t *v = eval(jl_getfieldnode_val(e), locals, nl); jl_value_t *gfargs[2] = {v, (jl_value_t*)jl_getfieldnode_name(e)}; return jl_f_get_field(NULL, gfargs, 2); } if (jl_is_lambda_info(e)) { return (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_null, (jl_lambda_info_t*)e); } if (jl_is_linenode(e)) { jl_lineno = jl_linenode_line(e); } return e; } jl_expr_t *ex = (jl_expr_t*)e; jl_value_t **args = &jl_cellref(ex->args,0); size_t nargs = jl_array_len(ex->args); if (ex->head == call_sym || ex->head == call1_sym) { jl_function_t *f = (jl_function_t*)eval(args[0], locals, nl); if (!jl_is_func(f)) jl_type_error("apply", (jl_value_t*)jl_function_type, (jl_value_t*)f); return do_call(f, &args[1], nargs-1, locals, nl); } else if (ex->head == assign_sym) { jl_value_t *sym = args[0]; size_t i; for (i=0; i < nl; i++) { if (locals[i*2] == sym) { return (locals[i*2+1] = eval(args[1], locals, nl)); } } jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)sym); jl_value_t *rhs = eval(args[1], locals, nl); jl_checked_assignment(b, rhs); return rhs; } else if (ex->head == new_sym) { jl_value_t *thetype = eval(args[0], locals, nl); jl_value_t *v=NULL; JL_GC_PUSH(&thetype, &v); assert(jl_is_structtype(thetype)); v = jl_new_struct_uninit((jl_datatype_t*)thetype); for(size_t i=1; i < nargs; i++) { jl_set_nth_field(v, i-1, eval(args[i], locals, nl)); } JL_GC_POP(); return v; } else if (ex->head == null_sym) { return (jl_value_t*)jl_nothing; } else if (ex->head == body_sym) { return eval_body(ex->args, locals, nl, 0); } else if (ex->head == exc_sym) { return jl_exception_in_transit; } else if (ex->head == static_typeof_sym) { return (jl_value_t*)jl_any_type; } else if (ex->head == method_sym) { jl_sym_t *fname = (jl_sym_t*)args[0]; jl_value_t **bp=NULL; jl_binding_t *b=NULL; jl_value_t *gf=NULL; int kw=0; if (jl_is_expr(fname)) { if (((jl_expr_t*)fname)->head == kw_sym) { kw = 1; fname = (jl_sym_t*)jl_exprarg(fname, 0); } gf = eval((jl_value_t*)fname, locals, nl); assert(jl_is_function(gf)); assert(jl_is_gf(gf)); if (!kw) { fname = (jl_sym_t*)jl_fieldref(jl_exprarg(fname, 2), 0); bp = &gf; } else { bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)gf)->env)->kwsorter; } assert(jl_is_symbol(fname)); } else { for (size_t i=0; i < nl; i++) { if (locals[i*2] == (jl_value_t*)fname) { bp = &locals[i*2+1]; break; } } if (bp == NULL) { b = jl_get_binding_for_method_def(jl_current_module, fname); bp = &b->value; } } jl_value_t *atypes=NULL, *meth=NULL, *tvars=NULL; JL_GC_PUSH(&atypes, &meth, &tvars); atypes = eval(args[1], locals, nl); meth = eval(args[2], locals, nl); tvars = eval(args[3], locals, nl); jl_method_def(fname, bp, b, (jl_tuple_t*)atypes, (jl_function_t*)meth, (jl_tuple_t*)tvars); JL_GC_POP(); return *bp; } else if (ex->head == const_sym) { jl_value_t *sym = args[0]; for (size_t i=0; i < nl; i++) { if (locals[i*2] == sym) { return (jl_value_t*)jl_nothing; } } jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)sym); jl_declare_constant(b); return (jl_value_t*)jl_nothing; } else if (ex->head == global_sym) { // create uninitialized mutable binding for "global x" decl // TODO: handle type decls for (size_t i=0; i < jl_array_len(ex->args); i++) { assert(jl_is_symbol(args[i])); jl_get_binding_wr(jl_current_module, (jl_sym_t*)args[i]); } return (jl_value_t*)jl_nothing; } else if (ex->head == abstracttype_sym) { jl_value_t *name = args[0]; jl_value_t *para = eval(args[1], locals, nl); jl_value_t *super = NULL; JL_GC_PUSH(¶, &super); jl_datatype_t *dt = jl_new_abstracttype(name, jl_any_type, (jl_tuple_t*)para); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); jl_checked_assignment(b, (jl_value_t*)dt); super = eval(args[2], locals, nl); jl_set_datatype_super(dt, super); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == bitstype_sym) { jl_value_t *name = args[0]; jl_value_t *super = NULL, *para = NULL, *vnb = NULL; JL_GC_PUSH(¶, &super, &vnb); para = eval(args[1], locals, nl); vnb = eval(args[2], locals, nl); if (!jl_is_long(vnb)) jl_errorf("invalid declaration of bits type %s", ((jl_sym_t*)name)->name); int32_t nb = jl_unbox_long(vnb); if (nb < 1 || nb>=(1<<23) || (nb&7) != 0) jl_errorf("invalid number of bits in type %s", ((jl_sym_t*)name)->name); jl_datatype_t *dt = jl_new_bitstype(name, jl_any_type, (jl_tuple_t*)para, nb); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); jl_checked_assignment(b, (jl_value_t*)dt); super = eval(args[3], locals, nl); jl_set_datatype_super(dt, super); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == compositetype_sym) { void jl_add_constructors(jl_datatype_t *t); jl_value_t *name = args[0]; jl_value_t *para = eval(args[1], locals, nl); jl_value_t *fnames = NULL; jl_value_t *super = NULL; jl_datatype_t *dt = NULL; JL_GC_PUSH(¶, &super, &fnames, &dt); fnames = eval(args[2], locals, nl); dt = jl_new_datatype((jl_sym_t*)name, jl_any_type, (jl_tuple_t*)para, (jl_tuple_t*)fnames, NULL, 0, args[6]==jl_true ? 1 : 0); dt->fptr = jl_f_ctor_trampoline; dt->ctor_factory = eval(args[3], locals, nl); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); jl_checked_assignment(b, (jl_value_t*)dt); inside_typedef = 1; dt->types = (jl_tuple_t*)eval(args[5], locals, nl); inside_typedef = 0; jl_check_type_tuple(dt->types, dt->name->name, "type definition"); super = eval(args[4], locals, nl); jl_set_datatype_super(dt, super); jl_compute_field_offsets(dt); jl_add_constructors(dt); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == macro_sym) { jl_sym_t *nm = (jl_sym_t*)args[0]; assert(jl_is_symbol(nm)); jl_function_t *f = (jl_function_t*)eval(args[1], locals, nl); assert(jl_is_function(f)); if (jl_boot_file_loaded && f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) { jl_lambda_info_t *li = f->linfo; li->ast = jl_compress_ast(li, li->ast); li->name = nm; } jl_set_global(jl_current_module, nm, (jl_value_t*)f); return (jl_value_t*)jl_nothing; } else if (ex->head == line_sym) { jl_lineno = jl_unbox_long(jl_exprarg(ex,0)); return (jl_value_t*)jl_nothing; } else if (ex->head == module_sym) { return jl_eval_module_expr(ex); } else if (ex->head == error_sym || ex->head == jl_continue_sym) { if (jl_is_byte_string(args[0])) jl_errorf("syntax: %s", jl_string_data(args[0])); jl_throw(args[0]); } jl_errorf("unsupported or misplaced expression %s", ex->head->name); return (jl_value_t*)jl_nothing; }
// `v` might be pointing to a field inlined in a structure therefore // `jl_typeof(v)` may not be the same with `vt` and only `vt` should be // used to determine the type of the value. // This is necessary to make sure that this function doesn't allocate any // memory through the Julia GC static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt, struct recur_list *depth) { size_t n = 0; if ((uintptr_t)vt < 4096U) { n += jl_printf(out, "<?#%p::%p>", (void*)v, (void*)vt); } else if ((uintptr_t)v < 4096U) { n += jl_printf(out, "<?#%p::", (void*)v); n += jl_static_show_x(out, (jl_value_t*)vt, depth); n += jl_printf(out, ">"); } else if (vt == jl_method_type) { jl_method_t *m = (jl_method_t*)v; n += jl_static_show_x(out, (jl_value_t*)m->module, depth); n += jl_printf(out, ".%s(...)", jl_symbol_name(m->name)); } else if (vt == jl_method_instance_type) { jl_method_instance_t *li = (jl_method_instance_t*)v; if (jl_is_method(li->def.method)) { jl_method_t *m = li->def.method; n += jl_static_show_x(out, (jl_value_t*)m->module, depth); if (li->specTypes) { n += jl_printf(out, "."); n += jl_show_svec(out, ((jl_datatype_t*)jl_unwrap_unionall(li->specTypes))->parameters, jl_symbol_name(m->name), "(", ")"); } else { n += jl_printf(out, ".%s(?)", jl_symbol_name(m->name)); } } else { n += jl_static_show_x(out, (jl_value_t*)li->def.module, depth); n += jl_printf(out, ".<toplevel thunk> -> "); n += jl_static_show_x(out, li->inferred, depth); } } else if (vt == jl_simplevector_type) { n += jl_show_svec(out, (jl_svec_t*)v, "svec", "(", ")"); } else if (vt == jl_datatype_type) { jl_datatype_t *dv = (jl_datatype_t*)v; jl_sym_t *globname = dv->name->mt != NULL ? dv->name->mt->name : NULL; int globfunc = 0; if (globname && !strchr(jl_symbol_name(globname), '#') && !strchr(jl_symbol_name(globname), '@') && dv->name->module && jl_binding_resolved_p(dv->name->module, globname)) { jl_binding_t *b = jl_get_binding(dv->name->module, globname); if (b && jl_typeof(b->value) == v) globfunc = 1; } jl_sym_t *sym = globfunc ? globname : dv->name->name; char *sn = jl_symbol_name(sym); int hidden = !globfunc && strchr(sn, '#'); size_t i = 0; int quote = 0; if (hidden) { n += jl_printf(out, "getfield("); } else if (globfunc) { n += jl_printf(out, "typeof("); } if (dv->name->module != jl_core_module || !jl_module_exports_p(jl_core_module, sym)) { n += jl_static_show_x(out, (jl_value_t*)dv->name->module, depth); if (!hidden) { n += jl_printf(out, "."); if (globfunc && !jl_id_start_char(u8_nextchar(sn, &i))) { n += jl_printf(out, ":("); quote = 1; } } } if (hidden) { n += jl_printf(out, ", Symbol(\""); n += jl_printf(out, "%s", sn); n += jl_printf(out, "\"))"); } else { n += jl_printf(out, "%s", sn); if (globfunc) { n += jl_printf(out, ")"); if (quote) n += jl_printf(out, ")"); } } if (dv->parameters && (jl_value_t*)dv != dv->name->wrapper && (jl_has_free_typevars(v) || (jl_value_t*)dv != (jl_value_t*)jl_tuple_type)) { size_t j, tlen = jl_nparams(dv); if (tlen > 0) { n += jl_printf(out, "{"); for (j = 0; j < tlen; j++) { jl_value_t *p = jl_tparam(dv,j); n += jl_static_show_x(out, p, depth); if (j != tlen-1) n += jl_printf(out, ", "); } n += jl_printf(out, "}"); } else if (dv->name == jl_tuple_typename) { n += jl_printf(out, "{}"); } } } else if (vt == jl_intrinsic_type) { int f = *(uint32_t*)jl_data_ptr(v); n += jl_printf(out, "#<intrinsic #%d %s>", f, jl_intrinsic_name(f)); } else if (vt == jl_int64_type) { n += jl_printf(out, "%" PRId64, *(int64_t*)v); } else if (vt == jl_int32_type) { n += jl_printf(out, "%" PRId32, *(int32_t*)v); } else if (vt == jl_int16_type) { n += jl_printf(out, "%" PRId16, *(int16_t*)v); } else if (vt == jl_int8_type) { n += jl_printf(out, "%" PRId8, *(int8_t*)v); } else if (vt == jl_uint64_type) { n += jl_printf(out, "0x%016" PRIx64, *(uint64_t*)v); } else if (vt == jl_uint32_type) { n += jl_printf(out, "0x%08" PRIx32, *(uint32_t*)v); } else if (vt == jl_uint16_type) { n += jl_printf(out, "0x%04" PRIx16, *(uint16_t*)v); } else if (vt == jl_uint8_type) { n += jl_printf(out, "0x%02" PRIx8, *(uint8_t*)v); } else if (jl_is_cpointer_type((jl_value_t*)vt)) { #ifdef _P64 n += jl_printf(out, "0x%016" PRIx64, *(uint64_t*)v); #else n += jl_printf(out, "0x%08" PRIx32, *(uint32_t*)v); #endif } else if (vt == jl_float32_type) { n += jl_printf(out, "%gf", *(float*)v); } else if (vt == jl_float64_type) { n += jl_printf(out, "%g", *(double*)v); } else if (vt == jl_bool_type) { n += jl_printf(out, "%s", *(uint8_t*)v ? "true" : "false"); } else if ((jl_value_t*)vt == jl_typeof(jl_nothing)) { n += jl_printf(out, "nothing"); } else if (vt == jl_string_type) { n += jl_printf(out, "\""); jl_uv_puts(out, jl_string_data(v), jl_string_len(v)); n += jl_string_len(v); n += jl_printf(out, "\""); } else if (v == jl_bottom_type) { n += jl_printf(out, "Union{}"); } else if (vt == jl_uniontype_type) { n += jl_printf(out, "Union{"); while (jl_is_uniontype(v)) { // tail-recurse on b to flatten the printing of the Union structure in the common case n += jl_static_show_x(out, ((jl_uniontype_t*)v)->a, depth); n += jl_printf(out, ", "); v = ((jl_uniontype_t*)v)->b; } n += jl_static_show_x(out, v, depth); n += jl_printf(out, "}"); } else if (vt == jl_unionall_type) { jl_unionall_t *ua = (jl_unionall_t*)v; n += jl_static_show_x(out, ua->body, depth); n += jl_printf(out, " where "); n += jl_static_show_x(out, (jl_value_t*)ua->var, depth->prev); } else if (vt == jl_tvar_type) { // show type-var bounds only if they aren't going to be printed by UnionAll later jl_tvar_t *var = (jl_tvar_t*)v; struct recur_list *p; int showbounds = 1; for (p = depth; p != NULL; p = p->prev) { if (jl_is_unionall(p->v) && ((jl_unionall_t*)p->v)->var == var) { showbounds = 0; break; } } jl_value_t *lb = var->lb, *ub = var->ub; if (showbounds && lb != jl_bottom_type) { // show type-var lower bound if it is defined int ua = jl_is_unionall(lb); if (ua) n += jl_printf(out, "("); n += jl_static_show_x(out, lb, depth); if (ua) n += jl_printf(out, ")"); n += jl_printf(out, "<:"); } n += jl_printf(out, "%s", jl_symbol_name(var->name)); if (showbounds && (ub != (jl_value_t*)jl_any_type || lb != jl_bottom_type)) { // show type-var upper bound if it is defined, or if we showed the lower bound int ua = jl_is_unionall(ub); n += jl_printf(out, "<:"); if (ua) n += jl_printf(out, "("); n += jl_static_show_x(out, ub, depth); if (ua) n += jl_printf(out, ")"); } } else if (vt == jl_module_type) { jl_module_t *m = (jl_module_t*)v; if (m->parent != m && m->parent != jl_main_module) { n += jl_static_show_x(out, (jl_value_t*)m->parent, depth); n += jl_printf(out, "."); } n += jl_printf(out, "%s", jl_symbol_name(m->name)); } else if (vt == jl_sym_type) { char *sn = jl_symbol_name((jl_sym_t*)v); int quoted = !jl_is_identifier(sn) && jl_operator_precedence(sn) == 0; if (quoted) n += jl_printf(out, "Symbol(\""); else n += jl_printf(out, ":"); n += jl_printf(out, "%s", sn); if (quoted) n += jl_printf(out, "\")"); } else if (vt == jl_ssavalue_type) { n += jl_printf(out, "SSAValue(%" PRIuPTR ")", (uintptr_t)((jl_ssavalue_t*)v)->id); } else if (vt == jl_globalref_type) { n += jl_static_show_x(out, (jl_value_t*)jl_globalref_mod(v), depth); n += jl_printf(out, ".%s", jl_symbol_name(jl_globalref_name(v))); } else if (vt == jl_labelnode_type) { n += jl_printf(out, "%" PRIuPTR ":", jl_labelnode_label(v)); } else if (vt == jl_gotonode_type) { n += jl_printf(out, "goto %" PRIuPTR, jl_gotonode_label(v)); } else if (vt == jl_quotenode_type) { jl_value_t *qv = *(jl_value_t**)v; if (!jl_is_symbol(qv)) { n += jl_printf(out, "quote "); } else { n += jl_printf(out, ":("); } n += jl_static_show_x(out, qv, depth); if (!jl_is_symbol(qv)) { n += jl_printf(out, " end"); } else { n += jl_printf(out, ")"); } } else if (vt == jl_newvarnode_type) { n += jl_printf(out, "<newvar "); n += jl_static_show_x(out, *(jl_value_t**)v, depth); n += jl_printf(out, ">"); } else if (vt == jl_linenumbernode_type) { n += jl_printf(out, "#= "); n += jl_static_show_x(out, jl_linenode_file(v), depth); n += jl_printf(out, ":%" PRIuPTR " =#", jl_linenode_line(v)); } else if (vt == jl_expr_type) { jl_expr_t *e = (jl_expr_t*)v; if (e->head == assign_sym && jl_array_len(e->args) == 2) { n += jl_static_show_x(out, jl_exprarg(e,0), depth); n += jl_printf(out, " = "); n += jl_static_show_x(out, jl_exprarg(e,1), depth); } else { char sep = ' '; if (e->head == body_sym) sep = '\n'; n += jl_printf(out, "Expr(:%s", jl_symbol_name(e->head)); size_t i, len = jl_array_len(e->args); for (i = 0; i < len; i++) { n += jl_printf(out, ",%c", sep); n += jl_static_show_x(out, jl_exprarg(e,i), depth); } n += jl_printf(out, ")::"); n += jl_static_show_x(out, e->etype, depth); } } else if (jl_is_array_type(vt)) { n += jl_static_show_x(out, (jl_value_t*)vt, depth); n += jl_printf(out, "["); size_t j, tlen = jl_array_len(v); jl_array_t *av = (jl_array_t*)v; jl_datatype_t *el_type = (jl_datatype_t*)jl_tparam0(vt); int nlsep = 0; if (av->flags.ptrarray) { // print arrays with newlines, unless the elements are probably small for (j = 0; j < tlen; j++) { jl_value_t *p = jl_array_ptr_ref(av, j); if (p != NULL && (uintptr_t)p >= 4096U) { jl_value_t *p_ty = jl_typeof(p); if ((uintptr_t)p_ty >= 4096U) { if (!jl_isbits(p_ty)) { nlsep = 1; break; } } } } } if (nlsep && tlen > 1) n += jl_printf(out, "\n "); for (j = 0; j < tlen; j++) { if (av->flags.ptrarray) { n += jl_static_show_x(out, jl_array_ptr_ref(v, j), depth); } else { char *ptr = ((char*)av->data) + j * av->elsize; n += jl_static_show_x_(out, (jl_value_t*)ptr, el_type, depth); } if (j != tlen - 1) n += jl_printf(out, nlsep ? ",\n " : ", "); } n += jl_printf(out, "]"); } else if (vt == jl_loaderror_type) { n += jl_printf(out, "LoadError(at "); n += jl_static_show_x(out, *(jl_value_t**)v, depth); // Access the field directly to avoid allocation n += jl_printf(out, " line %" PRIdPTR, ((intptr_t*)v)[1]); n += jl_printf(out, ": "); n += jl_static_show_x(out, ((jl_value_t**)v)[2], depth); n += jl_printf(out, ")"); } else if (vt == jl_errorexception_type) { n += jl_printf(out, "ErrorException("); n += jl_static_show_x(out, *(jl_value_t**)v, depth); n += jl_printf(out, ")"); } else if (jl_is_datatype(vt)) { int istuple = jl_is_tuple_type(vt); if (!istuple) n += jl_static_show_x(out, (jl_value_t*)vt, depth); n += jl_printf(out, "("); size_t nb = jl_datatype_size(vt); size_t tlen = jl_datatype_nfields(vt); if (nb > 0 && tlen == 0) { uint8_t *data = (uint8_t*)v; n += jl_printf(out, "0x"); for(int i = nb - 1; i >= 0; --i) n += jl_printf(out, "%02" PRIx8, data[i]); } else { size_t i = 0; if (vt == jl_typemap_entry_type) i = 1; for (; i < tlen; i++) { if (!istuple) { n += jl_printf(out, "%s", jl_symbol_name(jl_field_name(vt, i))); n += jl_printf(out, "="); } size_t offs = jl_field_offset(vt, i); char *fld_ptr = (char*)v + offs; if (jl_field_isptr(vt, i)) { n += jl_static_show_x(out, *(jl_value_t**)fld_ptr, depth); } else { jl_datatype_t *ft = (jl_datatype_t*)jl_field_type(vt, i); if (jl_is_uniontype(ft)) { uint8_t sel = ((uint8_t*)fld_ptr)[jl_field_size(vt, i) - 1]; ft = (jl_datatype_t*)jl_nth_union_component((jl_value_t*)ft, sel); } n += jl_static_show_x_(out, (jl_value_t*)fld_ptr, ft, depth); } if (istuple && tlen == 1) n += jl_printf(out, ","); else if (i != tlen - 1) n += jl_printf(out, ", "); } if (vt == jl_typemap_entry_type) { n += jl_printf(out, ", next=↩︎\n "); n += jl_static_show_x(out, jl_fieldref(v, 0), depth); } } n += jl_printf(out, ")"); } else { n += jl_printf(out, "<?#%p::", (void*)v); n += jl_static_show_x(out, (jl_value_t*)vt, depth); n += jl_printf(out, ">"); } return n; }
JL_DLLEXPORT jl_lambda_info_t *jl_new_lambda_info(jl_value_t *ast, jl_svec_t *tvars, jl_svec_t *sparams, jl_module_t *ctx) { jl_lambda_info_t *li = (jl_lambda_info_t*)newobj((jl_value_t*)jl_lambda_info_type, NWORDS(sizeof(jl_lambda_info_t))); li->ast = ast; li->rettype = (jl_value_t*)jl_any_type; li->file = null_sym; li->module = ctx; li->sparam_syms = tvars; li->sparam_vals = sparams; li->tfunc = jl_nothing; li->fptr = NULL; li->jlcall_api = 0; li->roots = NULL; li->functionObjects.functionObject = NULL; li->functionObjects.specFunctionObject = NULL; li->functionObjects.cFunctionList = NULL; li->functionID = 0; li->specFunctionID = 0; li->specTypes = NULL; li->inferred = 0; li->inInference = 0; li->inCompile = 0; li->unspecialized = NULL; li->specializations = NULL; li->name = anonymous_sym; li->def = li; li->line = 0; li->pure = 0; li->called = 0xff; li->needs_sparam_vals_ducttape = 0; if (ast && jl_is_expr(ast)) { jl_array_t *body = jl_lam_body((jl_expr_t*)ast)->args; if (has_meta(body, pure_sym)) li->pure = 1; jl_value_t *body1 = skip_meta(body); if (jl_is_linenode(body1)) { li->file = jl_linenode_file(body1); li->line = jl_linenode_line(body1); } else if (jl_is_expr(body1) && ((jl_expr_t*)body1)->head == line_sym) { li->file = (jl_sym_t*)jl_exprarg(body1, 1); li->line = jl_unbox_long(jl_exprarg(body1, 0)); } jl_array_t *vis = jl_lam_vinfo((jl_expr_t*)li->ast); jl_array_t *args = jl_lam_args((jl_expr_t*)li->ast); size_t narg = jl_array_len(args); uint8_t called=0; int i, j=0; for(i=1; i < narg && i <= 8; i++) { jl_value_t *ai = jl_cellref(args,i); if (ai == (jl_value_t*)unused_sym || !jl_is_symbol(ai)) continue; jl_value_t *vj; do { vj = jl_cellref(vis, j++); } while (jl_cellref(vj,0) != ai); if (jl_unbox_long(jl_cellref(vj,2))&64) called |= (1<<(i-1)); } li->called = called; if (tvars != jl_emptysvec) if (jl_has_intrinsics(li, (jl_expr_t*)ast, ctx)) li->needs_sparam_vals_ducttape = 1; } return li; }
// parse and eval a whole file, possibly reading from a string (`content`) jl_value_t *jl_parse_eval_all(const char *fname, const char *content, size_t contentlen) { if (in_pure_callback) jl_error("cannot use include inside a generated function"); jl_ast_context_t *ctx = jl_ast_ctx_enter(); fl_context_t *fl_ctx = &ctx->fl; value_t f, ast; size_t len = strlen(fname); f = cvalue_static_cstrn(fl_ctx, fname, len); fl_gc_handle(fl_ctx, &f); if (content != NULL) { value_t t = cvalue_static_cstrn(fl_ctx, content, contentlen); fl_gc_handle(fl_ctx, &t); ast = fl_applyn(fl_ctx, 2, symbol_value(symbol(fl_ctx, "jl-parse-string-stream")), t, f); fl_free_gc_handles(fl_ctx, 1); } else { assert(memchr(fname, 0, len) == NULL); // was checked already in jl_load ast = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-parse-file")), f); } fl_free_gc_handles(fl_ctx, 1); if (ast == fl_ctx->F) { jl_ast_ctx_leave(ctx); jl_errorf("could not open file %s", fname); } fl_gc_handle(fl_ctx, &ast); int last_lineno = jl_lineno; const char *last_filename = jl_filename; jl_lineno = 0; jl_filename = fname; jl_array_t *roots = NULL; jl_array_t **old_roots = ctx->roots; ctx->roots = &roots; jl_value_t *form=NULL, *result=jl_nothing; int err = 0; JL_GC_PUSH3(&roots, &form, &result); JL_TRY { assert(iscons(ast) && car_(ast) == symbol(fl_ctx,"toplevel")); ast = cdr_(ast); while (iscons(ast)) { value_t expansion = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-expand-to-thunk")), car_(ast)); form = scm_to_julia(fl_ctx, expansion, 0); jl_sym_t *head = NULL; if (jl_is_expr(form)) head = ((jl_expr_t*)form)->head; JL_SIGATOMIC_END(); if (head == jl_incomplete_sym) jl_errorf("syntax: %s", jl_string_data(jl_exprarg(form,0))); else if (head == error_sym) jl_interpret_toplevel_expr(form); else if (head == line_sym) jl_lineno = jl_unbox_long(jl_exprarg(form,0)); else if (jl_is_linenode(form)) jl_lineno = jl_linenode_line(form); else result = jl_toplevel_eval_flex(form, 1, 1); JL_SIGATOMIC_BEGIN(); ast = cdr_(ast); } } JL_CATCH { form = jl_pchar_to_string(fname, len); result = jl_box_long(jl_lineno); err = 1; } jl_lineno = last_lineno; jl_filename = last_filename; fl_free_gc_handles(fl_ctx, 1); ctx->roots = old_roots; jl_ast_ctx_leave(ctx); if (err) { if (jl_loaderror_type == NULL) jl_rethrow(); else jl_rethrow_other(jl_new_struct(jl_loaderror_type, form, result, jl_exception_in_transit)); } JL_GC_POP(); return result; }
DLLEXPORT size_t jl_static_show(JL_STREAM *out, jl_value_t *v) { // mimic jl_show, but never calling a julia method size_t n = 0; if (v == NULL) { n += JL_PRINTF(out, "<null>"); } else if (jl_is_lambda_info(v)) { jl_lambda_info_t *li = (jl_lambda_info_t*)v; n += jl_static_show(out, (jl_value_t*)li->module); n += JL_PRINTF(out, ".%s", li->name->name); if (li->specTypes) { n += jl_static_show(out, (jl_value_t*)li->specTypes); } else { n += JL_PRINTF(out, "(?)"); } } else if (jl_is_tuple(v)) { n += jl_show_tuple(out, (jl_tuple_t*)v, "(", ")", 1); } else if (jl_is_vararg_type(v)) { n += jl_static_show(out, jl_tparam0(v)); n += JL_PRINTF(out, "..."); } else if (jl_is_datatype(v)) { jl_datatype_t *dv = (jl_datatype_t*)v; if (dv->name->module != jl_core_module) { n += jl_static_show(out, (jl_value_t*)dv->name->module); JL_PUTS(".", out); n += 1; } n += JL_PRINTF(out, "%s", dv->name->name->name); if (dv->parameters) { size_t j, tlen = jl_tuple_len(dv->parameters); if (tlen > 0) { n += JL_PRINTF(out, "{"); for (j = 0; j < tlen; j++) { jl_value_t *p = jl_tupleref(dv->parameters,j); n += jl_static_show(out, p); if (j != tlen-1) n += JL_PRINTF(out, ", "); } n += JL_PRINTF(out, "}"); } } } else if (jl_is_func(v)) { if (jl_is_gf(v)) { n += JL_PRINTF(out, "%s", jl_gf_name(v)->name); } else { n += JL_PRINTF(out, "<# function>"); } } else if (jl_typeis(v, jl_intrinsic_type)) { n += JL_PRINTF(out, "<# intrinsic function %d>", *(uint32_t*)jl_data_ptr(v)); } else if (jl_is_int64(v)) { n += JL_PRINTF(out, "%d", jl_unbox_int64(v)); } else if (jl_is_int32(v)) { n += JL_PRINTF(out, "%d", jl_unbox_int32(v)); } else if (jl_typeis(v,jl_int16_type)) { n += JL_PRINTF(out, "%d", jl_unbox_int16(v)); } else if (jl_typeis(v,jl_int8_type)) { n += JL_PRINTF(out, "%d", jl_unbox_int8(v)); } else if (jl_is_uint64(v)) { n += JL_PRINTF(out, "0x%016x", jl_unbox_uint64(v)); } else if (jl_is_uint32(v)) { n += JL_PRINTF(out, "0x%08x", jl_unbox_uint32(v)); } else if (jl_typeis(v,jl_uint16_type)) { n += JL_PRINTF(out, "0x%04x", jl_unbox_uint16(v)); } else if (jl_typeis(v,jl_uint8_type)) { n += JL_PRINTF(out, "0x%02x", jl_unbox_uint8(v)); } else if (jl_is_cpointer(v)) { #ifdef _P64 n += JL_PRINTF(out, "0x%016x", jl_unbox_voidpointer(v)); #else n += JL_PRINTF(out, "0x%08x", jl_unbox_voidpointer(v)); #endif } else if (jl_is_float32(v)) { n += JL_PRINTF(out, "%g", jl_unbox_float32(v)); } else if (jl_is_float64(v)) { n += JL_PRINTF(out, "%g", jl_unbox_float64(v)); } else if (v == jl_true) { n += JL_PRINTF(out, "true"); } else if (v == jl_false) { n += JL_PRINTF(out, "false"); } else if (jl_is_byte_string(v)) { n += JL_PRINTF(out, "\"%s\"", jl_iostr_data(v)); } else if (v == jl_bottom_type) { n += JL_PRINTF(out, "Void"); } else if (jl_is_uniontype(v)) { n += JL_PRINTF(out, "Union"); n += jl_static_show(out, (jl_value_t*)((jl_uniontype_t*)v)->types); } else if (jl_is_typector(v)) { n += jl_static_show(out, ((jl_typector_t*)v)->body); } else if (jl_is_typevar(v)) { n += JL_PRINTF(out, "%s", ((jl_tvar_t*)v)->name->name); } else if (jl_is_module(v)) { jl_module_t *m = (jl_module_t*)v; if (m->parent != m && m->parent != jl_main_module) { n += jl_static_show(out, (jl_value_t*)m->parent); n += JL_PRINTF(out, "."); } n += JL_PRINTF(out, "%s", m->name->name); } else if (jl_is_symbol(v)) { n += JL_PRINTF(out, ":%s", ((jl_sym_t*)v)->name); } else if (jl_is_symbolnode(v)) { n += JL_PRINTF(out, "%s::", jl_symbolnode_sym(v)->name); n += jl_static_show(out, jl_symbolnode_type(v)); } else if (jl_is_getfieldnode(v)) { n += jl_static_show(out, jl_getfieldnode_val(v)); n += JL_PRINTF(out, ".%s", jl_getfieldnode_name(v)->name); n += JL_PRINTF(out, "::"); n += jl_static_show(out, jl_getfieldnode_type(v)); } else if (jl_is_labelnode(v)) { n += JL_PRINTF(out, "%d:", jl_labelnode_label(v)); } else if (jl_is_gotonode(v)) { n += JL_PRINTF(out, "goto %d", jl_gotonode_label(v)); } else if (jl_is_quotenode(v)) { n += JL_PRINTF(out, "quote "); n += jl_static_show(out, jl_fieldref(v,0)); n += JL_PRINTF(out, " end"); } else if (jl_is_newvarnode(v)) { n += JL_PRINTF(out, "<newvar "); n += jl_static_show(out, jl_fieldref(v,0)); n += JL_PRINTF(out, ">"); } else if (jl_is_topnode(v)) { n += JL_PRINTF(out, "top("); n += jl_static_show(out, jl_fieldref(v,0)); n += JL_PRINTF(out, ")"); } else if (jl_is_linenode(v)) { n += JL_PRINTF(out, "# line %d", jl_linenode_line(v)); } else if (jl_is_expr(v)) { jl_expr_t *e = (jl_expr_t*)v; if (e->head == assign_sym && jl_array_len(e->args) == 2) { n += jl_static_show(out, jl_exprarg(e,0)); n += JL_PRINTF(out, " = "); n += jl_static_show(out, jl_exprarg(e,1)); } else { char sep = ' '; if (e->head == body_sym) sep = '\n'; n += JL_PRINTF(out, "Expr(:%s", e->head->name); size_t i, len = jl_array_len(e->args); for (i = 0; i < len; i++) { n += JL_PRINTF(out, ",%c", sep); n += jl_static_show(out, jl_exprarg(e,i)); } n += JL_PRINTF(out, ")::"); n += jl_static_show(out, e->etype); } } else if (jl_is_array(v)) { n += jl_static_show(out, jl_typeof(v)); n += JL_PRINTF(out, "["); size_t j, tlen = jl_array_len(v); for (j = 0; j < tlen; j++) { n += jl_static_show(out, jl_arrayref((jl_array_t*)v,j)); if (j != tlen-1) n += JL_PRINTF(out, ", "); } n += JL_PRINTF(out, "]"); } else if (jl_typeis(v,jl_loaderror_type)) { n += JL_PRINTF(out, "LoadError(at "); n += jl_static_show(out, jl_fieldref(v, 0)); n += JL_PRINTF(out, " line "); n += jl_static_show(out, jl_fieldref(v, 1)); n += JL_PRINTF(out, ": "); n += jl_static_show(out, jl_fieldref(v, 2)); n += JL_PRINTF(out, ")"); } else if (jl_typeis(v,jl_errorexception_type)) { n += JL_PRINTF(out, "ErrorException("); n += jl_static_show(out, jl_fieldref(v, 0)); n += JL_PRINTF(out, ")"); } else if (jl_is_datatype(jl_typeof(v))) { jl_datatype_t *t = (jl_datatype_t*)jl_typeof(v); n += jl_static_show(out, (jl_value_t*)t); n += JL_PRINTF(out, "("); size_t nb = jl_datatype_size(t); size_t tlen = jl_tuple_len(t->names); if (nb > 0 && tlen == 0) { char *data = (char*)jl_data_ptr(v); n += JL_PRINTF(out, "0x"); for(int i=nb-1; i >= 0; --i) n += JL_PRINTF(out, "%02hhx", data[i]); } else { jl_value_t *fldval=NULL; JL_GC_PUSH1(&fldval); for (size_t i = 0; i < tlen; i++) { n += JL_PRINTF(out, ((jl_sym_t*)jl_tupleref(t->names, i))->name); //jl_fielddesc_t f = t->fields[i]; n += JL_PRINTF(out, "="); fldval = jl_get_nth_field(v, i); n += jl_static_show(out, fldval); if (i != tlen-1) n += JL_PRINTF(out, ", "); } JL_GC_POP(); } n += JL_PRINTF(out, ")"); } else { n += JL_PRINTF(out, "<?::"); n += jl_static_show(out, jl_typeof(v)); n += JL_PRINTF(out, ">"); } return n; }