DLLEXPORT void jl_restore_system_image(char *fname) { ios_t f; char *fpath = jl_find_file_in_path(fname); if (ios_file(&f, fpath, 1, 0, 0, 0) == NULL) { ios_printf(ios_stderr, "system image file not found\n"); exit(1); } #ifdef JL_GC_MARKSWEEP int en = jl_gc_is_enabled(); jl_gc_disable(); #endif tagtype_list = jl_alloc_cell_1d(0); jl_array_type->env = jl_deserialize_value(&f); jl_base_module = (jl_module_t*)jl_deserialize_value(&f); jl_current_module = (jl_module_t*)jl_deserialize_value(&f); jl_system_module = (jl_module_t*)jl_get_global(jl_base_module, jl_symbol("System")); jl_array_t *idtl = (jl_array_t*)jl_deserialize_value(&f); // rehash IdTables for(int i=0; i < idtl->length; i++) { jl_value_t *v = jl_cellref(idtl, i); jl_idtable_rehash(&((jl_array_t**)v)[1], ((jl_array_t**)v)[1]->length); } // cache builtin parametric types for(int i=0; i < tagtype_list->length; i++) { jl_value_t *v = jl_cellref(tagtype_list, i); uint32_t uid=0; if (jl_is_struct_type(v)) uid = ((jl_struct_type_t*)v)->uid; else if (jl_is_bits_type(v)) uid = ((jl_bits_type_t*)v)->uid; jl_cache_type_((jl_tag_type_t*)v); if (jl_is_struct_type(v)) ((jl_struct_type_t*)v)->uid = uid; else if (jl_is_bits_type(v)) ((jl_bits_type_t*)v)->uid = uid; } jl_get_builtin_hooks(); jl_get_system_hooks(); jl_boot_file_loaded = 1; jl_typeinf_func = (jl_function_t*)jl_get_global(jl_system_module, jl_symbol("typeinf_ext")); jl_init_box_caches(); //jl_deserialize_finalizers(&f); jl_set_t_uid_ctr(read_int32(&f)); jl_set_gs_ctr(read_int32(&f)); htable_reset(&backref_table, 0); ios_t ss; ios_mem(&ss, 0); ios_copyuntil(&ss, &f, '\0'); ios_close(&f); if (fpath != fname) free(fpath); #ifdef JL_GC_MARKSWEEP if (en) jl_gc_enable(); #endif // TODO: there is no exception handler here! jl_load_file_string(ss.buf); ios_close(&ss); }
jl_value_t *jl_eval_module_expr(jl_expr_t *ex) { static arraylist_t module_stack; static int initialized=0; 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) { 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; int newbase = 0; if (parent_module == jl_main_module && name == jl_symbol("Base")) { base_module_conflict = (jl_base_module != NULL); jl_old_base_module = jl_base_module; // pick up Base module during bootstrap jl_base_module = newm; newbase = base_module_conflict; } // 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_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; jl_rethrow(); } JL_GC_POP(); jl_current_module = last_module; jl_current_task->current_module = task_last_m; if (newbase) { // reinitialize global variables // to pick up new types from Base jl_errorexception_type = NULL; jl_get_system_hooks(); jl_get_uv_hooks(1); jl_current_task->tls = jl_nothing; } #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 (jl_current_module == jl_main_module) { while (module_stack.len > 0) { jl_module_run_initializer((jl_module_t *) arraylist_pop(&module_stack)); } } return jl_nothing; }