static jl_module_t *eval_import_path(jl_array_t *args) { // in A.B.C, first find a binding for A in the chain of module scopes // following parent links. then evaluate the rest of the path from there. jl_sym_t *var = (jl_sym_t*)jl_cellref(args,0); assert(jl_is_symbol(var)); jl_module_t *m = jl_current_module; while (1) { jl_binding_t *mb = jl_get_binding(m, var); if (mb != NULL) { if (mb->value == NULL || !jl_is_module(mb->value)) jl_errorf("invalid module path"); m = (jl_module_t*)mb->value; break; } if (m == jl_main_module) jl_errorf("in module path: %s not defined", var->name); m = m->parent; } for(size_t i=1; i < args->length-1; i++) { jl_value_t *s = jl_cellref(args,i); assert(jl_is_symbol(s)); m = (jl_module_t*)jl_eval_global_var(m, (jl_sym_t*)s); if (!jl_is_module(m)) jl_errorf("invalid import statement"); } return m; }
static jl_module_t *eval_import_path_(jl_array_t *args, int retrying) { // in .A.B.C, first find a binding for A in the chain of module scopes // following parent links. then evaluate the rest of the path from there. // in A.B, look for A in Main first. jl_sym_t *var = (jl_sym_t*)jl_cellref(args,0); size_t i=1; assert(jl_is_symbol(var)); jl_module_t *m; if (var != dot_sym) { m = jl_main_module; } else { m = jl_current_module; while (1) { var = (jl_sym_t*)jl_cellref(args,i); i++; if (var != dot_sym) break; m = m->parent; } } while (1) { if (jl_binding_resolved_p(m, var)) { jl_binding_t *mb = jl_get_binding(m, var); assert(mb != NULL); if (mb->owner == m || mb->imported) { m = (jl_module_t*)mb->value; if (m == NULL || !jl_is_module(m)) jl_errorf("invalid module path"); break; } } if (m == jl_main_module) { if (!retrying) { if (require_func == NULL && jl_base_module != NULL) require_func = jl_get_global(jl_base_module, jl_symbol("require")); if (require_func != NULL) { jl_value_t *str = jl_cstr_to_string(var->name); JL_GC_PUSH1(&str); jl_apply((jl_function_t*)require_func, &str, 1); JL_GC_POP(); return eval_import_path_(args, 1); } } } jl_errorf("in module path: %s not defined", var->name); } for(; i < jl_array_len(args)-1; i++) { jl_value_t *s = jl_cellref(args,i); assert(jl_is_symbol(s)); m = (jl_module_t*)jl_eval_global_var(m, (jl_sym_t*)s); if (!jl_is_module(m)) jl_errorf("invalid import statement"); } return m; }
static jl_module_t *find_submodule_named(jl_module_t *module, const char *name) { jl_sym_t *s = jl_symbol_lookup(name); if (!s) return NULL; jl_binding_t *b = jl_get_binding(module, s); if (!b) return NULL; return (jl_is_module(b->value)) ? (jl_module_t *)b->value : NULL; }
static jl_module_t *eval_import_path(jl_array_t *args) { jl_module_t *m = jl_root_module; for(size_t i=0; i < args->length-1; i++) { jl_value_t *s = jl_cellref(args,i); assert(jl_is_symbol(s)); m = (jl_module_t*)jl_eval_global_var(m, (jl_sym_t*)s); if (!jl_is_module(m)) jl_errorf("invalid import statement"); } return m; }
DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_value_t *rhs) { if (b->constp && b->value != NULL) { if (!jl_egal(rhs, b->value)) { if (jl_typeof(rhs) != jl_typeof(b->value) || jl_is_type(rhs) || jl_is_function(rhs) || jl_is_module(rhs)) { jl_errorf("invalid redefinition of constant %s", b->name->name); } JL_PRINTF(JL_STDERR,"Warning: redefining constant %s\n",b->name->name); } } b->value = rhs; }
JL_DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_value_t *rhs) { if (b->constp && b->value != NULL) { if (!jl_egal(rhs, b->value)) { if (jl_typeof(rhs) != jl_typeof(b->value) || jl_is_type(rhs) || jl_is_function(rhs) || jl_is_module(rhs)) { jl_errorf("invalid redefinition of constant %s", jl_symbol_name(b->name)); } jl_printf(JL_STDERR, "WARNING: redefining constant %s\n", jl_symbol_name(b->name)); } } b->value = rhs; jl_gc_wb_binding(b, rhs); }
jl_value_t *jl_eval_dot_expr(jl_module_t *m, jl_value_t *x, jl_value_t *f, int fast) { jl_value_t **args; JL_GC_PUSHARGS(args, 3); args[1] = jl_toplevel_eval_flex(m, x, fast, 0); args[2] = jl_toplevel_eval_flex(m, f, fast, 0); if (jl_is_module(args[1])) { JL_TYPECHK("getfield", symbol, args[2]); args[0] = jl_eval_global_var((jl_module_t*)args[1], (jl_sym_t*)args[2]); } else { args[0] = jl_eval_global_var(jl_base_relative_to(m), jl_symbol("getproperty")); args[0] = jl_apply(args, 3); } JL_GC_POP(); return args[0]; }
jl_value_t *jl_resolve_globals(jl_value_t *expr, jl_lambda_info_t *lam) { if (jl_is_symbol(expr)) { if (lam->def->module == NULL) return expr; return jl_module_globalref(lam->def->module, (jl_sym_t*)expr); } else if (jl_is_expr(expr)) { jl_expr_t *e = (jl_expr_t*)expr; if (jl_is_toplevel_only_expr(expr) || e->head == const_sym || e->head == copyast_sym || e->head == global_sym || e->head == quote_sym || e->head == inert_sym || e->head == line_sym || e->head == meta_sym || e->head == inbounds_sym || e->head == boundscheck_sym || e->head == simdloop_sym) { } else { if (e->head == call_sym && jl_expr_nargs(e) == 3 && jl_is_quotenode(jl_exprarg(e,2)) && lam->def->module != NULL) { // replace getfield(module_expr, :sym) with GlobalRef jl_value_t *s = jl_fieldref(jl_exprarg(e,2),0); jl_value_t *fe = jl_exprarg(e,0); if (jl_is_symbol(s) && jl_is_globalref(fe)) { jl_value_t *f = jl_static_eval(fe, NULL, lam->def->module, lam, 0, 0); if (f == jl_builtin_getfield) { jl_value_t *me = jl_exprarg(e,1); if (jl_is_globalref(me) || (jl_is_symbol(me) && jl_binding_resolved_p(lam->def->module, (jl_sym_t*)me))) { jl_value_t *m = jl_static_eval(me, NULL, lam->def->module, lam, 0, 0); if (m && jl_is_module(m)) return jl_module_globalref((jl_module_t*)m, (jl_sym_t*)s); } } } } size_t i = 0; if (e->head == method_sym || e->head == abstracttype_sym || e->head == compositetype_sym || e->head == bitstype_sym || e->head == module_sym) i++; for(; i < jl_array_len(e->args); i++) { jl_exprargset(e, i, jl_resolve_globals(jl_exprarg(e,i), lam)); } } } return expr; }
static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *mod) { if (fl_isnumber(fl_ctx, e)) { int64_t i64; if (isfixnum(e)) { i64 = numval(e); } else { assert(iscprim(e)); cprim_t *cp = (cprim_t*)ptr(e); numerictype_t nt = cp_numtype(cp); switch (nt) { case T_DOUBLE: return (jl_value_t*)jl_box_float64(*(double*)cp_data(cp)); case T_FLOAT: return (jl_value_t*)jl_box_float32(*(float*)cp_data(cp)); case T_UINT8: return (jl_value_t*)jl_box_uint8(*(uint8_t*)cp_data(cp)); case T_UINT16: return (jl_value_t*)jl_box_uint16(*(uint16_t*)cp_data(cp)); case T_UINT32: return (jl_value_t*)jl_box_uint32(*(uint32_t*)cp_data(cp)); case T_UINT64: return (jl_value_t*)jl_box_uint64(*(uint64_t*)cp_data(cp)); default: ; } i64 = conv_to_int64(cp_data(cp), nt); } #ifdef _P64 return (jl_value_t*)jl_box_int64(i64); #else if (i64 > (int64_t)S32_MAX || i64 < (int64_t)S32_MIN) return (jl_value_t*)jl_box_int64(i64); else return (jl_value_t*)jl_box_int32((int32_t)i64); #endif } if (issymbol(e)) { if (e == jl_ast_ctx(fl_ctx)->true_sym) return jl_true; else if (e == jl_ast_ctx(fl_ctx)->false_sym) return jl_false; return (jl_value_t*)scmsym_to_julia(fl_ctx, e); } if (fl_isstring(fl_ctx, e)) return jl_pchar_to_string((char*)cvalue_data(e), cvalue_len(e)); if (iscons(e) || e == fl_ctx->NIL) { value_t hd; jl_sym_t *sym; if (e == fl_ctx->NIL) { hd = e; } else { hd = car_(e); if (hd == jl_ast_ctx(fl_ctx)->ssavalue_sym) return jl_box_ssavalue(numval(car_(cdr_(e)))); else if (hd == jl_ast_ctx(fl_ctx)->slot_sym) return jl_box_slotnumber(numval(car_(cdr_(e)))); else if (hd == jl_ast_ctx(fl_ctx)->null_sym && llength(e) == 1) return jl_nothing; } if (issymbol(hd)) sym = scmsym_to_julia(fl_ctx, hd); else sym = list_sym; size_t n = llength(e)-1; if (issymbol(hd)) e = cdr_(e); else n++; // nodes with special representations jl_value_t *ex = NULL, *temp = NULL; if (sym == line_sym && (n == 1 || n == 2)) { jl_value_t *linenum = scm_to_julia_(fl_ctx, car_(e), mod); jl_value_t *file = jl_nothing; JL_GC_PUSH2(&linenum, &file); if (n == 2) file = scm_to_julia_(fl_ctx, car_(cdr_(e)), mod); temp = jl_new_struct(jl_linenumbernode_type, linenum, file); JL_GC_POP(); return temp; } JL_GC_PUSH1(&ex); if (sym == label_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = jl_new_struct(jl_labelnode_type, ex); } else if (sym == goto_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = jl_new_struct(jl_gotonode_type, ex); } else if (sym == newvar_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = jl_new_struct(jl_newvarnode_type, ex); } else if (sym == globalref_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = scm_to_julia_(fl_ctx, car_(cdr_(e)), mod); assert(jl_is_module(ex)); assert(jl_is_symbol(temp)); temp = jl_module_globalref((jl_module_t*)ex, (jl_sym_t*)temp); } else if (sym == top_sym) { assert(mod && "top should not be generated by the parser"); ex = scm_to_julia_(fl_ctx, car_(e), mod); assert(jl_is_symbol(ex)); temp = jl_module_globalref(jl_base_relative_to(mod), (jl_sym_t*)ex); } else if (sym == core_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); assert(jl_is_symbol(ex)); temp = jl_module_globalref(jl_core_module, (jl_sym_t*)ex); } else if (sym == inert_sym || (sym == quote_sym && (!iscons(car_(e))))) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = jl_new_struct(jl_quotenode_type, ex); } if (temp) { JL_GC_POP(); return temp; } ex = (jl_value_t*)jl_exprn(sym, n); size_t i; for (i = 0; i < n; i++) { assert(iscons(e)); jl_array_ptr_set(((jl_expr_t*)ex)->args, i, scm_to_julia_(fl_ctx, car_(e), mod)); e = cdr_(e); } if (sym == lambda_sym) ex = (jl_value_t*)jl_new_code_info_from_ast((jl_expr_t*)ex); JL_GC_POP(); if (sym == list_sym) return (jl_value_t*)((jl_expr_t*)ex)->args; return (jl_value_t*)ex; } if (iscprim(e) && cp_class((cprim_t*)ptr(e)) == fl_ctx->wchartype) { uint32_t c, u = *(uint32_t*)cp_data((cprim_t*)ptr(e)); if (u < 0x80) { c = u << 24; } else { c = ((u << 0) & 0x0000003f) | ((u << 2) & 0x00003f00) | ((u << 4) & 0x003f0000) | ((u << 6) & 0x3f000000); c = u < 0x00000800 ? (c << 16) | 0xc0800000 : u < 0x00010000 ? (c << 8) | 0xe0808000 : (c << 0) | 0xf0808080 ; } return jl_box_char(c); } if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jl_ast_ctx(fl_ctx)->jvtype) { return *(jl_value_t**)cv_data((cvalue_t*)ptr(e)); } jl_error("malformed tree"); }
jl_value_t *jl_eval_module_expr(jl_expr_t *ex) { static arraylist_t module_stack; static int initialized=0; static jl_module_t *outermost = NULL; if (!initialized) { arraylist_new(&module_stack, 0); initialized = 1; } assert(ex->head == module_sym); jl_module_t *last_module = jl_current_module; if (jl_array_len(ex->args) != 3 || !jl_is_expr(jl_exprarg(ex,2))) { jl_error("syntax: malformed module expression"); } int std_imports = (jl_exprarg(ex,0)==jl_true); jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1); if (!jl_is_symbol(name)) { jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name); } jl_module_t *parent_module = jl_current_module; jl_binding_t *b = jl_get_binding_wr(parent_module, name); jl_declare_constant(b); if (b->value != NULL) { if (!jl_is_module(b->value)) { jl_errorf("invalid redefinition of constant %s", name->name); } if (jl_generating_output() && jl_options.incremental) { jl_errorf("cannot replace module %s during incremental compile", name->name); } if (!jl_generating_output()) { // suppress warning "replacing module Core.Inference" during bootstrapping jl_printf(JL_STDERR, "WARNING: replacing module %s\n", name->name); } } jl_module_t *newm = jl_new_module(name); newm->parent = parent_module; b->value = (jl_value_t*)newm; jl_gc_wb_binding(b, newm); if (parent_module == jl_main_module && name == jl_symbol("Base")) { // pick up Base module during bootstrap jl_old_base_module = jl_base_module; jl_base_module = newm; // reinitialize global variables // to pick up new types from Base jl_errorexception_type = NULL; jl_argumenterror_type = NULL; jl_methoderror_type = NULL; jl_loaderror_type = NULL; jl_current_task->tls = jl_nothing; // may contain an entry for :SOURCE_FILE that is not valid in the new base } // export all modules from Main if (parent_module == jl_main_module) jl_module_export(jl_main_module, name); // add standard imports unless baremodule if (std_imports) { if (jl_base_module != NULL) { jl_add_standard_imports(newm); } } JL_GC_PUSH1(&last_module); jl_module_t *task_last_m = jl_current_task->current_module; jl_current_task->current_module = jl_current_module = newm; jl_module_t *prev_outermost = outermost; size_t stackidx = module_stack.len; if (outermost == NULL) outermost = newm; jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 2))->args; JL_TRY { for(int i=0; i < jl_array_len(exprs); i++) { // process toplevel form jl_value_t *form = jl_cellref(exprs, i); (void)jl_toplevel_eval_flex(form, 1); } } JL_CATCH { jl_current_module = last_module; jl_current_task->current_module = task_last_m; outermost = prev_outermost; module_stack.len = stackidx; jl_rethrow(); } JL_GC_POP(); jl_current_module = last_module; jl_current_task->current_module = task_last_m; outermost = prev_outermost; #if 0 // some optional post-processing steps 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->owner==newm) 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); */ } } #endif arraylist_push(&module_stack, newm); if (outermost == NULL || jl_current_module == jl_main_module) { size_t i, l=module_stack.len; for(i = stackidx; i < l; i++) { jl_module_load_time_initialize((jl_module_t*)module_stack.items[i]); } assert(module_stack.len == l); module_stack.len = stackidx; } return (jl_value_t*)newm; }
// TODO: add locks around global state mutation operations jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex) { jl_ptls_t ptls = jl_get_ptls_states(); assert(ex->head == module_sym); if (jl_array_len(ex->args) != 3 || !jl_is_expr(jl_exprarg(ex, 2))) { jl_error("syntax: malformed module expression"); } int std_imports = (jl_exprarg(ex, 0) == jl_true); jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1); if (!jl_is_symbol(name)) { jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name); } jl_module_t *newm = jl_new_module(name); jl_value_t *form = (jl_value_t*)newm; JL_GC_PUSH1(&form); ptrhash_put(&jl_current_modules, (void*)newm, (void*)((uintptr_t)HT_NOTFOUND + 1)); // copy parent environment info into submodule newm->uuid = parent_module->uuid; if (jl_base_module && (jl_value_t*)parent_module == jl_get_global(jl_base_module, jl_symbol("__toplevel__"))) { newm->parent = newm; jl_register_root_module(newm); } else { jl_binding_t *b = jl_get_binding_wr(parent_module, name, 1); jl_declare_constant(b); if (b->value != NULL) { if (!jl_is_module(b->value)) { jl_errorf("invalid redefinition of constant %s", jl_symbol_name(name)); } if (jl_generating_output()) { jl_errorf("cannot replace module %s during compilation", jl_symbol_name(name)); } jl_printf(JL_STDERR, "WARNING: replacing module %s.\n", jl_symbol_name(name)); // create a hidden gc root for the old module uintptr_t *refcnt = (uintptr_t*)ptrhash_bp(&jl_current_modules, (void*)b->value); *refcnt += 1; } newm->parent = parent_module; b->value = (jl_value_t*)newm; jl_gc_wb_binding(b, newm); } if (parent_module == jl_main_module && name == jl_symbol("Base")) { // pick up Base module during bootstrap jl_base_module = newm; } size_t last_age = ptls->world_age; // add standard imports unless baremodule if (std_imports) { if (jl_base_module != NULL) { jl_add_standard_imports(newm); } // add `eval` function form = jl_call_scm_on_ast("module-default-defs", (jl_value_t*)ex, newm); ptls->world_age = jl_world_counter; jl_toplevel_eval_flex(newm, form, 0, 1); form = NULL; } jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 2))->args; for (int i = 0; i < jl_array_len(exprs); i++) { // process toplevel form ptls->world_age = jl_world_counter; form = jl_expand_stmt(jl_array_ptr_ref(exprs, i), newm); ptls->world_age = jl_world_counter; (void)jl_toplevel_eval_flex(newm, form, 1, 1); } ptls->world_age = last_age; #if 0 // some optional post-processing steps 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 (jl_symbol_name(b->name)[0]=='@' && !b->exportp && b->owner == newm) 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", jl_symbol_name(b->name), jl_symbol_name(newm->name)); */ } } #endif uintptr_t *refcnt = (uintptr_t*)ptrhash_bp(&jl_current_modules, (void*)newm); assert(*refcnt > (uintptr_t)HT_NOTFOUND); *refcnt -= 1; // newm should be reachable from somewhere else by now if (jl_module_init_order == NULL) jl_module_init_order = jl_alloc_vec_any(0); jl_array_ptr_1d_push(jl_module_init_order, (jl_value_t*)newm); // defer init of children until parent is done being defined // then initialize all in definition-finished order // at build time, don't run them at all (defer for runtime) if (!jl_generating_output()) { if (!ptrhash_has(&jl_current_modules, (void*)newm->parent)) { size_t i, l = jl_array_len(jl_module_init_order); size_t ns = 0; form = (jl_value_t*)jl_alloc_vec_any(0); for (i = 0; i < l; i++) { jl_module_t *m = (jl_module_t*)jl_array_ptr_ref(jl_module_init_order, i); if (jl_is_submodule(m, newm)) { jl_array_ptr_1d_push((jl_array_t*)form, (jl_value_t*)m); } else if (ns++ != i) { jl_array_ptr_set(jl_module_init_order, ns - 1, (jl_value_t*)m); } } if (ns < l) jl_array_del_end(jl_module_init_order, l - ns); l = jl_array_len(form); for (i = 0; i < l; i++) { jl_module_t *m = (jl_module_t*)jl_array_ptr_ref(form, i); JL_GC_PROMISE_ROOTED(m); jl_module_run_initializer(m); } } } JL_GC_POP(); return (jl_value_t*)newm; }
static jl_module_t *eval_import_path_(jl_array_t *args, int retrying) { // in .A.B.C, first find a binding for A in the chain of module scopes // following parent links. then evaluate the rest of the path from there. // in A.B, look for A in Main first. jl_sym_t *var = (jl_sym_t*)jl_cellref(args,0); size_t i=1; if (!jl_is_symbol(var)) jl_type_error("import or using", (jl_value_t*)jl_sym_type, (jl_value_t*)var); jl_module_t *m; if (var != dot_sym) { m = jl_main_module; } else { m = jl_current_module; while (1) { var = (jl_sym_t*)jl_cellref(args,i); if (!jl_is_symbol(var)) jl_type_error("import or using", (jl_value_t*)jl_sym_type, (jl_value_t*)var); i++; if (var != dot_sym) { if (i == jl_array_len(args)) return m; else break; } m = m->parent; } } while (1) { if (jl_binding_resolved_p(m, var)) { jl_binding_t *mb = jl_get_binding(m, var); jl_module_t *m0 = m; int isimp = jl_is_imported(m, var); assert(mb != NULL); if (mb->owner == m0 || isimp) { m = (jl_module_t*)mb->value; if ((mb->owner == m0 && m != NULL && !jl_is_module(m)) || (isimp && (m == NULL || !jl_is_module(m)))) jl_errorf("invalid module path (%s does not name a module)", var->name); // If the binding has been resolved but is (1) undefined, and (2) owned // by the module we're importing into, then allow the import into the // undefined variable (by setting m back to m0). if (m == NULL) m = m0; else break; } } if (m == jl_main_module) { if (!retrying && i==1) { // (i==1) => no require() for relative imports if (require_func == NULL && jl_base_module != NULL) require_func = jl_get_global(jl_base_module, jl_symbol("require")); if (require_func != NULL) { jl_apply((jl_function_t*)require_func, (jl_value_t**)&var, 1); return eval_import_path_(args, 1); } } } if (retrying && require_func) { jl_printf(JL_STDERR, "WARNING: requiring \"%s\" did not define a corresponding module.\n", var->name); return NULL; } else { jl_errorf("in module path: %s not defined", var->name); } } for(; i < jl_array_len(args)-1; i++) { jl_value_t *s = jl_cellref(args,i); assert(jl_is_symbol(s)); m = (jl_module_t*)jl_eval_global_var(m, (jl_sym_t*)s); if (!jl_is_module(m)) jl_errorf("invalid import statement"); } return m; }
jl_value_t *jl_eval_module_expr(jl_expr_t *ex) { jl_ptls_t ptls = jl_get_ptls_states(); static arraylist_t module_stack; static int initialized=0; static jl_module_t *outermost = NULL; if (!initialized) { arraylist_new(&module_stack, 0); initialized = 1; } assert(ex->head == module_sym); jl_module_t *last_module = ptls->current_module; if (jl_array_len(ex->args) != 3 || !jl_is_expr(jl_exprarg(ex,2))) { jl_error("syntax: malformed module expression"); } int std_imports = (jl_exprarg(ex,0)==jl_true); jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1); if (!jl_is_symbol(name)) { jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name); } jl_module_t *parent_module = ptls->current_module; jl_binding_t *b = jl_get_binding_wr(parent_module, name); jl_declare_constant(b); if (b->value != NULL) { if (!jl_is_module(b->value)) { jl_errorf("invalid redefinition of constant %s", jl_symbol_name(name)); } if (jl_generating_output()) { jl_errorf("cannot replace module %s during compilation", jl_symbol_name(name)); } jl_printf(JL_STDERR, "WARNING: replacing module %s\n", jl_symbol_name(name)); } jl_module_t *newm = jl_new_module(name); newm->parent = parent_module; b->value = (jl_value_t*)newm; jl_gc_wb_binding(b, newm); if (parent_module == jl_main_module && name == jl_symbol("Base")) { // pick up Base module during bootstrap jl_base_module = newm; } // export all modules from Main if (parent_module == jl_main_module) jl_module_export(jl_main_module, name); // add standard imports unless baremodule if (std_imports) { if (jl_base_module != NULL) { jl_add_standard_imports(newm); } } jl_value_t *defaultdefs = NULL, *form = NULL; JL_GC_PUSH3(&last_module, &defaultdefs, &form); jl_module_t *task_last_m = ptls->current_task->current_module; ptls->current_task->current_module = ptls->current_module = newm; jl_module_t *prev_outermost = outermost; size_t stackidx = module_stack.len; if (outermost == NULL) outermost = newm; if (std_imports) { // add `eval` function defaultdefs = jl_call_scm_on_ast("module-default-defs", (jl_value_t*)ex); jl_toplevel_eval_flex(defaultdefs, 0, 1); defaultdefs = NULL; } jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 2))->args; JL_TRY { for(int i=0; i < jl_array_len(exprs); i++) { // process toplevel form form = jl_expand(jl_array_ptr_ref(exprs, i)); (void)jl_toplevel_eval_flex(form, 1, 1); } } JL_CATCH { ptls->current_module = last_module; ptls->current_task->current_module = task_last_m; outermost = prev_outermost; module_stack.len = stackidx; jl_rethrow(); } JL_GC_POP(); ptls->current_module = last_module; ptls->current_task->current_module = task_last_m; outermost = prev_outermost; #if 0 // some optional post-processing steps 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 (jl_symbol_name(b->name)[0]=='@' && !b->exportp && b->owner == newm) 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", jl_symbol_name(b->name), jl_symbol_name(newm->name)); */ } } #endif arraylist_push(&module_stack, newm); if (outermost == NULL || ptls->current_module == jl_main_module) { JL_TRY { size_t i, l=module_stack.len; for(i = stackidx; i < l; i++) { jl_module_load_time_initialize((jl_module_t*)module_stack.items[i]); } assert(module_stack.len == l); module_stack.len = stackidx; } JL_CATCH { module_stack.len = stackidx; jl_rethrow(); } }
jl_value_t *jl_resolve_globals(jl_value_t *expr, jl_module_t *module, jl_svec_t *sparam_vals) { if (jl_is_symbol(expr)) { if (module == NULL) return expr; return jl_module_globalref(module, (jl_sym_t*)expr); } else if (jl_is_expr(expr)) { jl_expr_t *e = (jl_expr_t*)expr; if (e->head == global_sym) { // execute the side-effects of "global x" decl immediately: // creates uninitialized mutable binding in module for each global jl_toplevel_eval_flex(module, expr, 0, 1); expr = jl_nothing; } if (jl_is_toplevel_only_expr(expr) || e->head == const_sym || e->head == copyast_sym || e->head == quote_sym || e->head == inert_sym || e->head == meta_sym || e->head == inbounds_sym || e->head == boundscheck_sym || e->head == simdloop_sym) { // ignore these } else { if (e->head == call_sym && jl_expr_nargs(e) == 3 && jl_is_quotenode(jl_exprarg(e, 2)) && module != NULL) { // replace getfield(module_expr, :sym) with GlobalRef jl_value_t *s = jl_fieldref(jl_exprarg(e, 2), 0); jl_value_t *fe = jl_exprarg(e, 0); if (jl_is_symbol(s) && jl_is_globalref(fe)) { jl_binding_t *b = jl_get_binding(jl_globalref_mod(fe), jl_globalref_name(fe)); jl_value_t *f = NULL; if (b && b->constp) { f = b->value; } if (f == jl_builtin_getfield) { jl_value_t *me = jl_exprarg(e, 1); jl_module_t *me_mod = NULL; jl_sym_t *me_sym = NULL; if (jl_is_globalref(me)) { me_mod = jl_globalref_mod(me); me_sym = jl_globalref_name(me); } else if (jl_is_symbol(me) && jl_binding_resolved_p(module, (jl_sym_t*)me)) { me_mod = module; me_sym = (jl_sym_t*)me; } if (me_mod && me_sym) { jl_binding_t *b = jl_get_binding(me_mod, me_sym); if (b && b->constp) { jl_value_t *m = b->value; if (m && jl_is_module(m)) { return jl_module_globalref((jl_module_t*)m, (jl_sym_t*)s); } } } } } } size_t i = 0, nargs = jl_array_len(e->args); if (e->head == foreigncall_sym) { JL_NARGSV(ccall method definition, 5); // (fptr, rt, at, cc, narg) jl_value_t *rt = jl_exprarg(e, 1); jl_value_t *at = jl_exprarg(e, 2); if (!jl_is_type(rt)) { JL_TRY { rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals); } JL_CATCH { if (jl_typeis(jl_exception_in_transit, jl_errorexception_type)) jl_error("could not evaluate ccall return type (it might depend on a local variable)"); else jl_rethrow(); } jl_exprargset(e, 1, rt); } if (!jl_is_svec(at)) { JL_TRY { at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); } JL_CATCH { if (jl_typeis(jl_exception_in_transit, jl_errorexception_type)) jl_error("could not evaluate ccall argument type (it might depend on a local variable)"); else jl_rethrow(); } jl_exprargset(e, 2, at); } if (jl_is_svec(rt)) jl_error("ccall: missing return type"); JL_TYPECHK(ccall method definition, type, rt); JL_TYPECHK(ccall method definition, simplevector, at); JL_TYPECHK(ccall method definition, quotenode, jl_exprarg(e, 3)); JL_TYPECHK(ccall method definition, symbol, *(jl_value_t**)jl_exprarg(e, 3)); JL_TYPECHK(ccall method definition, long, jl_exprarg(e, 4)); }
static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, int eo) { if (fl_isnumber(fl_ctx, e)) { int64_t i64; if (isfixnum(e)) { i64 = numval(e); } else { assert(iscprim(e)); cprim_t *cp = (cprim_t*)ptr(e); numerictype_t nt = cp_numtype(cp); switch (nt) { case T_DOUBLE: return (jl_value_t*)jl_box_float64(*(double*)cp_data(cp)); case T_FLOAT: return (jl_value_t*)jl_box_float32(*(float*)cp_data(cp)); case T_UINT8: return (jl_value_t*)jl_box_uint8(*(uint8_t*)cp_data(cp)); case T_UINT16: return (jl_value_t*)jl_box_uint16(*(uint16_t*)cp_data(cp)); case T_UINT32: return (jl_value_t*)jl_box_uint32(*(uint32_t*)cp_data(cp)); case T_UINT64: return (jl_value_t*)jl_box_uint64(*(uint64_t*)cp_data(cp)); default: ; } i64 = conv_to_int64(cp_data(cp), nt); } #ifdef _P64 return (jl_value_t*)jl_box_int64(i64); #else if (i64 > (int64_t)S32_MAX || i64 < (int64_t)S32_MIN) return (jl_value_t*)jl_box_int64(i64); else return (jl_value_t*)jl_box_int32((int32_t)i64); #endif } if (issymbol(e)) { if (e == jl_ast_ctx(fl_ctx)->true_sym) return jl_true; else if (e == jl_ast_ctx(fl_ctx)->false_sym) return jl_false; return (jl_value_t*)scmsym_to_julia(fl_ctx, e); } if (fl_isstring(fl_ctx, e)) return jl_pchar_to_string((char*)cvalue_data(e), cvalue_len(e)); if (iscons(e) || e == fl_ctx->NIL) { value_t hd; jl_sym_t *sym; if (e == fl_ctx->NIL) { hd = e; } else { hd = car_(e); if (hd == jl_ast_ctx(fl_ctx)->ssavalue_sym) return jl_box_ssavalue(numval(car_(cdr_(e)))); else if (hd == jl_ast_ctx(fl_ctx)->slot_sym) return jl_box_slotnumber(numval(car_(cdr_(e)))); else if (hd == jl_ast_ctx(fl_ctx)->null_sym && llength(e) == 1) return jl_nothing; } if (issymbol(hd)) sym = scmsym_to_julia(fl_ctx, hd); else sym = list_sym; size_t n = llength(e)-1; if (issymbol(hd)) e = cdr_(e); else n++; if (!eo) { if (sym == line_sym && n==1) { jl_value_t *linenum = scm_to_julia_(fl_ctx, car_(e), 0); JL_GC_PUSH1(&linenum); jl_value_t *temp = jl_new_struct(jl_linenumbernode_type, linenum); JL_GC_POP(); return temp; } jl_value_t *scmv = NULL, *temp = NULL; JL_GC_PUSH1(&scmv); if (sym == label_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = jl_new_struct(jl_labelnode_type, scmv); JL_GC_POP(); return temp; } if (sym == goto_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = jl_new_struct(jl_gotonode_type, scmv); JL_GC_POP(); return temp; } if (sym == inert_sym || (sym == quote_sym && (!iscons(car_(e))))) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = jl_new_struct(jl_quotenode_type, scmv); JL_GC_POP(); return temp; } if (sym == top_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); assert(jl_is_symbol(scmv)); temp = jl_module_globalref(jl_base_relative_to(jl_current_module), (jl_sym_t*)scmv); JL_GC_POP(); return temp; } if (sym == core_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); assert(jl_is_symbol(scmv)); temp = jl_module_globalref(jl_core_module, (jl_sym_t*)scmv); JL_GC_POP(); return temp; } if (sym == globalref_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = scm_to_julia_(fl_ctx,car_(cdr_(e)),0); assert(jl_is_module(scmv)); assert(jl_is_symbol(temp)); temp = jl_module_globalref((jl_module_t*)scmv, (jl_sym_t*)temp); JL_GC_POP(); return temp; } if (sym == newvar_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = jl_new_struct(jl_newvarnode_type, scmv); JL_GC_POP(); return temp; } JL_GC_POP(); } else if (sym == inert_sym && !iscons(car_(e))) { sym = quote_sym; } jl_value_t *ex = (jl_value_t*)jl_exprn(sym, n); JL_GC_PUSH1(&ex); // allocate a fresh args array for empty exprs passed to macros if (eo && n == 0) { ((jl_expr_t*)ex)->args = jl_alloc_vec_any(0); jl_gc_wb(ex, ((jl_expr_t*)ex)->args); } size_t i; for(i=0; i < n; i++) { assert(iscons(e)); jl_array_ptr_set(((jl_expr_t*)ex)->args, i, scm_to_julia_(fl_ctx, car_(e), eo)); e = cdr_(e); } if (sym == lambda_sym) ex = (jl_value_t*)jl_new_lambda_info_from_ast((jl_expr_t*)ex); JL_GC_POP(); if (sym == list_sym) return (jl_value_t*)((jl_expr_t*)ex)->args; return (jl_value_t*)ex; } if (iscprim(e) && cp_class((cprim_t*)ptr(e)) == fl_ctx->wchartype) { return jl_box32(jl_char_type, *(int32_t*)cp_data((cprim_t*)ptr(e))); } if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jl_ast_ctx(fl_ctx)->jvtype) { return *(jl_value_t**)cv_data((cvalue_t*)ptr(e)); } jl_error("malformed tree"); return jl_nothing; }
jl_value_t *jl_toplevel_eval_flex(jl_value_t *e, int fast) { //jl_show(ex); //jl_printf(JL_STDOUT, "\n"); if (!jl_is_expr(e)) return jl_interpret_toplevel_expr(e); jl_expr_t *ex = (jl_expr_t*)e; if (ex->head == null_sym || ex->head == error_sym) { // expression types simple enough not to need expansion return jl_interpret_toplevel_expr(e); } if (ex->head == module_sym) { return jl_eval_module_expr(ex); } // handle import, using, importall, export toplevel-only forms if (ex->head == importall_sym) { jl_module_t *m = eval_import_path(ex->args); if (m==NULL) return jl_nothing; jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, jl_array_len(ex->args)-1); if (!jl_is_symbol(name)) jl_error("syntax: malformed \"importall\" statement"); m = (jl_module_t*)jl_eval_global_var(m, name); if (!jl_is_module(m)) jl_errorf("invalid %s statement: name exists but does not refer to a module", ex->head->name); jl_module_importall(jl_current_module, m); return jl_nothing; } if (ex->head == using_sym) { jl_module_t *m = eval_import_path(ex->args); if (m==NULL) return jl_nothing; jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, jl_array_len(ex->args)-1); if (!jl_is_symbol(name)) jl_error("syntax: malformed \"using\" statement"); jl_module_t *u = (jl_module_t*)jl_eval_global_var(m, name); if (jl_is_module(u)) { jl_module_using(jl_current_module, u); } else { jl_module_use(jl_current_module, m, name); } return jl_nothing; } if (ex->head == import_sym) { jl_module_t *m = eval_import_path(ex->args); if (m==NULL) return jl_nothing; jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, jl_array_len(ex->args)-1); if (!jl_is_symbol(name)) jl_error("syntax: malformed \"import\" statement"); jl_module_import(jl_current_module, m, name); return jl_nothing; } if (ex->head == export_sym) { for(size_t i=0; i < jl_array_len(ex->args); i++) { jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, i); if (!jl_is_symbol(name)) jl_error("syntax: malformed \"export\" statement"); jl_module_export(jl_current_module, name); } return jl_nothing; } if (ex->head == toplevel_sym) { int i=0; jl_value_t *res=jl_nothing; for(i=0; i < jl_array_len(ex->args); i++) { res = jl_toplevel_eval_flex(jl_cellref(ex->args, i), fast); } return res; } jl_value_t *thunk=NULL; jl_value_t *result; jl_lambda_info_t *thk=NULL; int ewc = 0; JL_GC_PUSH3(&thunk, &thk, &ex); if (ex->head != body_sym && ex->head != thunk_sym && ex->head != return_sym && ex->head != method_sym) { // not yet expanded ex = (jl_expr_t*)jl_expand(e); } jl_sym_t *head = jl_is_expr(ex) ? ex->head : NULL; if (head == toplevel_sym) { int i=0; jl_value_t *res=jl_nothing; for(i=0; i < jl_array_len(ex->args); i++) { res = jl_toplevel_eval_flex(jl_cellref(ex->args, i), fast); } JL_GC_POP(); return res; } if (head == thunk_sym) { thk = (jl_lambda_info_t*)jl_exprarg(ex,0); assert(jl_is_lambda_info(thk)); assert(jl_is_expr(thk->ast)); ewc = jl_eval_with_compiler_p((jl_expr_t*)thk->ast, jl_lam_body((jl_expr_t*)thk->ast), fast, jl_current_module); if (!ewc) { if (jl_lam_vars_captured((jl_expr_t*)thk->ast)) { // interpreter doesn't handle closure environment ewc = 1; } } } else { if (head && jl_eval_with_compiler_p(NULL, (jl_expr_t*)ex, fast, jl_current_module)) { thk = jl_wrap_expr((jl_value_t*)ex); ewc = 1; } else { if (head == body_sym) { result = jl_toplevel_eval_body(ex->args); } else if (jl_is_toplevel_only_expr((jl_value_t*)ex)) { result = jl_toplevel_eval((jl_value_t*)ex); } else { result = jl_interpret_toplevel_expr((jl_value_t*)ex); } JL_GC_POP(); return result; } } if (ewc) { thunk = (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_emptysvec, thk); if (!jl_in_inference) { jl_type_infer(thk, (jl_tupletype_t*)jl_typeof(jl_emptytuple), thk); } result = jl_apply((jl_function_t*)thunk, NULL, 0); } else { result = jl_interpret_toplevel_thunk(thk); } JL_GC_POP(); return result; }
jl_value_t *jl_toplevel_eval_flex(jl_value_t *e, int fast, int *plineno) { //jl_show(ex); //JL_PRINTF(JL_STDOUT, "\n"); if (!jl_is_expr(e)) return jl_interpret_toplevel_expr(e); jl_expr_t *ex = (jl_expr_t*)e; if (ex->head == null_sym || ex->head == error_sym) { // expression types simple enough not to need expansion return jl_interpret_toplevel_expr(e); } if (ex->head == module_sym) { return jl_eval_module_expr(ex, plineno); } // handle import, export toplevel-only forms if (ex->head == importall_sym) { jl_module_t *m = eval_import_path(ex->args); jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, ex->args->length-1); assert(jl_is_symbol(name)); m = (jl_module_t*)jl_eval_global_var(m, name); if (!jl_is_module(m)) jl_errorf("invalid import statement"); jl_module_importall(jl_current_module, m); return jl_nothing; } if (ex->head == import_sym) { jl_module_t *m = eval_import_path(ex->args); jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, ex->args->length-1); assert(jl_is_symbol(name)); jl_module_import(jl_current_module, m, name); return jl_nothing; } if (ex->head == export_sym) { for(size_t i=0; i < ex->args->length; i++) { jl_module_export(jl_current_module, (jl_sym_t*)jl_cellref(ex->args, i)); } return jl_nothing; } jl_value_t *thunk=NULL; jl_value_t *result; jl_lambda_info_t *thk=NULL; int ewc = 0; JL_GC_PUSH(&thunk, &thk, &ex); if (ex->head != body_sym && ex->head != thunk_sym) { // not yet expanded ex = (jl_expr_t*)jl_expand(e); } if (jl_is_expr(ex) && ex->head == thunk_sym) { thk = (jl_lambda_info_t*)jl_exprarg(ex,0); assert(jl_is_lambda_info(thk)); ewc = jl_eval_with_compiler_p(jl_lam_body((jl_expr_t*)thk->ast), fast); if (!ewc) { jl_array_t *vinfos = jl_lam_vinfo((jl_expr_t*)thk->ast); int i; for(i=0; i < vinfos->length; i++) { if (jl_vinfo_capt((jl_array_t*)jl_cellref(vinfos,i))) { // interpreter doesn't handle closure environment ewc = 1; break; } } } } else { if (jl_is_expr(ex) && jl_eval_with_compiler_p((jl_expr_t*)ex, fast)) { thk = jl_wrap_expr((jl_value_t*)ex); ewc = 1; } else { result = jl_interpret_toplevel_expr((jl_value_t*)ex); JL_GC_POP(); return result; } } if (ewc) { thunk = (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_null, thk); if (!jl_in_inference) { jl_type_infer(thk, jl_tuple_type, thk); } result = jl_apply((jl_function_t*)thunk, NULL, 0); } else { result = jl_interpret_toplevel_thunk(thk); } 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; }