static jl_methlist_t *jl_deserialize_methlist(ios_t *s) { jl_methlist_t *ml = NULL; jl_methlist_t **pnext = &ml; while (1) { jl_value_t *sig = jl_deserialize_value(s); if (sig == NULL) break; jl_methlist_t *node = (jl_methlist_t*)allocb(sizeof(jl_methlist_t)); node->sig = (jl_tuple_t*)sig; assert(jl_is_tuple(sig)); node->va = read_int8(s); node->tvars = (jl_tuple_t*)jl_deserialize_value(s); node->func = (jl_function_t*)jl_deserialize_value(s); node->invokes = (jl_methtable_t*)jl_deserialize_value(s); node->next = NULL; *pnext = node; pnext = &node->next; } return ml; }
DLLEXPORT jl_value_t *jl_uncompress_ast(jl_tuple_t *data) { jl_array_t *bytes = (jl_array_t*)jl_tupleref(data, 0); tree_literal_values = (jl_array_t*)jl_tupleref(data, 1); ios_t src; jl_ios_mem(&src, 0); ios_setbuf(&src, bytes->data, bytes->length, 0); src.size = bytes->length; int en = jl_gc_is_enabled(); jl_gc_disable(); jl_gc_ephemeral_on(); jl_value_t *v = jl_deserialize_value(&src); jl_gc_ephemeral_off(); if (en) jl_gc_enable(); tree_literal_values = NULL; return v; }
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); }
static jl_value_t *jl_deserialize_value(ios_t *s) { int pos = ios_pos(s); int32_t tag = read_uint8(s); if (tag == Null_tag) return NULL; if (tag == 0) { tag = read_uint8(s); return (jl_value_t*)ptrhash_get(&deser_tag, (void*)(ptrint_t)tag); } if (tag == BackRef_tag) { assert(tree_literal_values == NULL); ptrint_t offs = read_int32(s); void **bp = ptrhash_bp(&backref_table, (void*)(ptrint_t)offs); assert(*bp != HT_NOTFOUND); return (jl_value_t*)*bp; } jl_value_t *vtag=(jl_value_t*)ptrhash_get(&deser_tag,(void*)(ptrint_t)tag); if (tag >= VALUE_TAGS) { return vtag; } int usetable = (tree_literal_values == NULL); size_t i; if (vtag == (jl_value_t*)jl_tuple_type || vtag == (jl_value_t*)LongTuple_tag) { size_t len; if (vtag == (jl_value_t*)jl_tuple_type) len = read_uint8(s); else len = read_int32(s); jl_tuple_t *tu = jl_alloc_tuple_uninit(len); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)tu); for(i=0; i < len; i++) jl_tupleset(tu, i, jl_deserialize_value(s)); return (jl_value_t*)tu; } else if (vtag == (jl_value_t*)jl_symbol_type || vtag == (jl_value_t*)LongSymbol_tag) { size_t len; if (vtag == (jl_value_t*)jl_symbol_type) len = read_uint8(s); else len = read_int32(s); char *name = alloca(len+1); ios_read(s, name, len); name[len] = '\0'; jl_value_t *s = (jl_value_t*)jl_symbol(name); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, s); return s; } else if (vtag == (jl_value_t*)jl_array_type) { jl_value_t *aty = jl_deserialize_value(s); jl_value_t *elty = jl_tparam0(aty); int16_t ndims = jl_unbox_long(jl_tparam1(aty)); size_t *dims = alloca(ndims*sizeof(size_t)); for(i=0; i < ndims; i++) dims[i] = jl_unbox_long(jl_deserialize_value(s)); jl_array_t *a = jl_new_array_((jl_type_t*)aty, ndims, dims); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)a); if (jl_is_bits_type(elty)) { size_t tot = a->length * a->elsize; ios_read(s, a->data, tot); } else { for(i=0; i < a->length; i++) { ((jl_value_t**)a->data)[i] = jl_deserialize_value(s); } } return (jl_value_t*)a; } else if (vtag == (jl_value_t*)jl_expr_type || vtag == (jl_value_t*)LongExpr_tag) { size_t len; if (vtag == (jl_value_t*)jl_expr_type) len = read_uint8(s); else len = read_int32(s); jl_expr_t *e = jl_exprn((jl_sym_t*)jl_deserialize_value(s), len); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)e); e->etype = jl_deserialize_value(s); for(i=0; i < len; i++) { jl_cellset(e->args, i, jl_deserialize_value(s)); } return (jl_value_t*)e; } else if (vtag == (jl_value_t*)LiteralVal_tag) { return jl_cellref(tree_literal_values, read_uint16(s)); } else if (vtag == (jl_value_t*)jl_tvar_type) { jl_tvar_t *tv = (jl_tvar_t*)newobj((jl_type_t*)jl_tvar_type, 4); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, tv); tv->name = (jl_sym_t*)jl_deserialize_value(s); tv->lb = jl_deserialize_value(s); tv->ub = jl_deserialize_value(s); tv->bound = read_int8(s); return (jl_value_t*)tv; } else if (vtag == (jl_value_t*)jl_func_kind) { jl_value_t *ftype = jl_deserialize_value(s); jl_function_t *f = (jl_function_t*)newobj((jl_type_t*)ftype, 3); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, f); f->linfo = (jl_lambda_info_t*)jl_deserialize_value(s); f->env = jl_deserialize_value(s); f->fptr = jl_deserialize_fptr(s); if (f->fptr == NULL) { f->fptr = &jl_trampoline; } return (jl_value_t*)f; } else if (vtag == (jl_value_t*)jl_lambda_info_type) { jl_lambda_info_t *li = (jl_lambda_info_t*)newobj((jl_type_t*)jl_lambda_info_type, LAMBDA_INFO_NW); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, li); li->ast = jl_deserialize_value(s); li->sparams = (jl_tuple_t*)jl_deserialize_value(s); li->tfunc = jl_deserialize_value(s); li->name = (jl_sym_t*)jl_deserialize_value(s); li->specTypes = jl_deserialize_value(s); li->specializations = (jl_array_t*)jl_deserialize_value(s); li->inferred = jl_deserialize_value(s); li->file = jl_deserialize_value(s); li->line = jl_deserialize_value(s); li->module = (jl_module_t*)jl_deserialize_value(s); li->fptr = NULL; li->roots = NULL; li->functionObject = NULL; li->inInference = 0; li->inCompile = 0; li->unspecialized = NULL; return (jl_value_t*)li; } else if (vtag == (jl_value_t*)jl_module_type) { jl_module_t *m = jl_new_module(anonymous_sym); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, m); m->name = (jl_sym_t*)jl_deserialize_value(s); while (1) { jl_value_t *name = jl_deserialize_value(s); if (name == NULL) break; jl_binding_t *b = jl_get_binding_wr(m, (jl_sym_t*)name); b->value = jl_deserialize_value(s); b->type = (jl_type_t*)jl_deserialize_value(s); b->constp = read_int8(s); b->exportp = read_int8(s); } while (1) { jl_value_t *name = jl_deserialize_value(s); if (name == NULL) break; jl_set_expander(m, (jl_sym_t*)name, (jl_function_t*)jl_deserialize_value(s)); } return (jl_value_t*)m; } else if (vtag == (jl_value_t*)jl_methtable_type) { jl_methtable_t *mt = (jl_methtable_t*)allocobj(sizeof(jl_methtable_t)); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, mt); mt->type = (jl_type_t*)jl_methtable_type; mt->defs = jl_deserialize_methlist(s); mt->cache = jl_deserialize_methlist(s); mt->cache_1arg = (jl_array_t*)jl_deserialize_value(s); mt->max_args = read_int32(s); return (jl_value_t*)mt; } else if (vtag == (jl_value_t*)SmallInt64_tag) { jl_value_t *v = jl_box_int64(read_int32(s)); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, v); return v; } else if (vtag == (jl_value_t*)jl_bits_kind) { jl_bits_type_t *bt = (jl_bits_type_t*)jl_deserialize_value(s); int nby = bt->nbits/8; char *data = alloca(nby); ios_read(s, data, nby); jl_value_t *v=NULL; if (bt == jl_int32_type) v = jl_box_int32(*(int32_t*)data); else if (bt == jl_int64_type) v = jl_box_int64(*(int64_t*)data); else if (bt == jl_bool_type) v = jl_box_bool(*(int8_t*)data); else { switch (bt->nbits) { case 8: v = jl_box8 (bt, *(int8_t*) data); break; case 16: v = jl_box16(bt, *(int16_t*)data); break; case 32: v = jl_box32(bt, *(int32_t*)data); break; case 64: v = jl_box64(bt, *(int64_t*)data); break; default: v = (jl_value_t*)allocobj(sizeof(void*)+nby); v->type = (jl_type_t*)bt; memcpy(jl_bits_data(v), data, nby); } } if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, v); return v; } else if (vtag == (jl_value_t*)jl_struct_kind) { jl_struct_type_t *typ = (jl_struct_type_t*)jl_deserialize_value(s); if (typ == jl_struct_kind || typ == jl_bits_kind) return jl_deserialize_tag_type(s, typ, pos); size_t nf = typ->names->length; jl_value_t *v = jl_new_struct_uninit(typ); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, v); for(i=0; i < nf; i++) { ((jl_value_t**)v)[i+1] = jl_deserialize_value(s); } // TODO: put WeakRefs on the weak_refs list return v; } else if (vtag == (jl_value_t*)jl_tag_kind) { return jl_deserialize_tag_type(s, jl_tag_kind, pos); } assert(0); return NULL; }
static jl_value_t *jl_deserialize_tag_type(ios_t *s, jl_struct_type_t *kind, int pos) { if (kind == jl_struct_kind) { jl_struct_type_t *st = (jl_struct_type_t*)newobj((jl_type_t*)jl_struct_kind, STRUCT_TYPE_NW); st->instance = NULL; ptrhash_put(&backref_table, (void*)(ptrint_t)pos, st); st->name = (jl_typename_t*)jl_deserialize_value(s); st->parameters = (jl_tuple_t*)jl_deserialize_value(s); st->super = (jl_tag_type_t*)jl_deserialize_value(s); st->names = (jl_tuple_t*)jl_deserialize_value(s); st->types = (jl_tuple_t*)jl_deserialize_value(s); st->ctor_factory = jl_deserialize_value(s); st->env = jl_deserialize_value(s); st->linfo = (jl_lambda_info_t*)jl_deserialize_value(s); st->fptr = jl_deserialize_fptr(s); st->uid = read_int32(s);; if (st->name == jl_array_type->name) { // builtin types are not serialized, so their caches aren't // explicitly saved. so we reconstruct the caches of builtin // parametric types here. jl_cell_1d_push(tagtype_list, (jl_value_t*)st); } return (jl_value_t*)st; } else if (kind == jl_bits_kind) { int form = read_uint8(s); jl_bits_type_t *bt; if (form == 2) bt = jl_int32_type; else if (form == 3) bt = jl_bool_type; else if (form == 4) bt = jl_int64_type; else bt = (jl_bits_type_t*)newobj((jl_type_t*)jl_bits_kind, BITS_TYPE_NW); ptrhash_put(&backref_table, (void*)(ptrint_t)pos, bt); bt->name = (jl_typename_t*)jl_deserialize_value(s); bt->parameters = (jl_tuple_t*)jl_deserialize_value(s); size_t nbits = read_int32(s); bt->nbits = nbits; bt->bnbits = jl_box_int32(nbits); bt->fptr = NULL; bt->env = NULL; bt->linfo = NULL; bt->super = (jl_tag_type_t*)jl_deserialize_value(s); bt->uid = read_int32(s); if (bt->name == jl_pointer_type->name) { jl_cell_1d_push(tagtype_list, (jl_value_t*)bt); } return (jl_value_t*)bt; } else { assert(kind == jl_tag_kind); jl_tag_type_t *tt = (jl_tag_type_t*)newobj((jl_type_t*)jl_tag_kind, TAG_TYPE_NW); ptrhash_put(&backref_table, (void*)(ptrint_t)pos, tt); tt->name = (jl_typename_t*)jl_deserialize_value(s); tt->parameters = (jl_tuple_t*)jl_deserialize_value(s); tt->super = (jl_tag_type_t*)jl_deserialize_value(s); tt->fptr = NULL; tt->env = NULL; tt->linfo = NULL; if (tt->name == jl_type_type->name || tt->name == jl_seq_type->name || tt->name == jl_abstractarray_type->name) { jl_cell_1d_push(tagtype_list, (jl_value_t*)tt); } return (jl_value_t*)tt; } assert(0); return NULL; }
static jl_value_t *jl_deserialize_value(ios_t *s) { int pos = ios_pos(s); int32_t tag = read_uint8(s); if (tag == Null_tag) return NULL; if (tag == 0) { tag = read_uint8(s); jl_value_t *v = ptrhash_get(&deser_tag, (void*)(ptrint_t)tag); assert(v != HT_NOTFOUND); return v; } if (tag == BackRef_tag || tag == ShortBackRef_tag) { assert(tree_literal_values == NULL); ptrint_t offs = (tag == BackRef_tag) ? read_int32(s) : read_uint16(s); void **bp = ptrhash_bp(&backref_table, (void*)(ptrint_t)offs); assert(*bp != HT_NOTFOUND); return (jl_value_t*)*bp; } jl_value_t *vtag=(jl_value_t*)ptrhash_get(&deser_tag,(void*)(ptrint_t)tag); if (tag >= VALUE_TAGS) { return vtag; } int usetable = (tree_literal_values == NULL); size_t i; if (vtag == (jl_value_t*)jl_tuple_type || vtag == (jl_value_t*)LongTuple_tag) { size_t len; if (vtag == (jl_value_t*)jl_tuple_type) len = read_uint8(s); else len = read_int32(s); jl_tuple_t *tu = jl_alloc_tuple_uninit(len); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)tu); for(i=0; i < len; i++) jl_tupleset(tu, i, jl_deserialize_value(s)); return (jl_value_t*)tu; } else if (vtag == (jl_value_t*)jl_symbol_type || vtag == (jl_value_t*)LongSymbol_tag) { size_t len; if (vtag == (jl_value_t*)jl_symbol_type) len = read_uint8(s); else len = read_int32(s); char *name = alloca(len+1); ios_read(s, name, len); name[len] = '\0'; jl_value_t *s = (jl_value_t*)jl_symbol(name); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, s); return s; } else if (vtag == (jl_value_t*)jl_array_type) { jl_value_t *aty = jl_deserialize_value(s); jl_value_t *elty = jl_tparam0(aty); int16_t ndims = jl_unbox_long(jl_tparam1(aty)); size_t *dims = alloca(ndims*sizeof(size_t)); for(i=0; i < ndims; i++) dims[i] = jl_unbox_long(jl_deserialize_value(s)); jl_array_t *a = jl_new_array_((jl_type_t*)aty, ndims, dims); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)a); if (jl_is_bits_type(elty)) { size_t tot = jl_array_len(a) * a->elsize; ios_read(s, jl_array_data(a), tot); } else { for(i=0; i < jl_array_len(a); i++) { ((jl_value_t**)a->data)[i] = jl_deserialize_value(s); } } return (jl_value_t*)a; } else if (vtag == (jl_value_t*)jl_expr_type || vtag == (jl_value_t*)LongExpr_tag) { size_t len; if (vtag == (jl_value_t*)jl_expr_type) len = read_uint8(s); else len = read_int32(s); jl_expr_t *e = jl_exprn((jl_sym_t*)jl_deserialize_value(s), len); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)e); e->etype = jl_deserialize_value(s); for(i=0; i < len; i++) { jl_cellset(e->args, i, jl_deserialize_value(s)); } return (jl_value_t*)e; } else if (vtag == (jl_value_t*)LiteralVal_tag) { return jl_cellref(tree_literal_values, read_uint16(s)); } else if (vtag == (jl_value_t*)jl_tvar_type) { jl_tvar_t *tv = (jl_tvar_t*)newobj((jl_type_t*)jl_tvar_type, 4); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, tv); tv->name = (jl_sym_t*)jl_deserialize_value(s); tv->lb = jl_deserialize_value(s); tv->ub = jl_deserialize_value(s); tv->bound = read_int8(s); return (jl_value_t*)tv; } else if (vtag == (jl_value_t*)jl_function_type) { jl_function_t *f = (jl_function_t*)newobj((jl_type_t*)jl_function_type, 3); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, f); f->linfo = (jl_lambda_info_t*)jl_deserialize_value(s); f->env = jl_deserialize_value(s); f->fptr = jl_deserialize_fptr(s); return (jl_value_t*)f; } else if (vtag == (jl_value_t*)jl_lambda_info_type) { jl_lambda_info_t *li = (jl_lambda_info_t*)newobj((jl_type_t*)jl_lambda_info_type, LAMBDA_INFO_NW); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, li); li->ast = jl_deserialize_value(s); li->sparams = (jl_tuple_t*)jl_deserialize_value(s); li->tfunc = jl_deserialize_value(s); li->name = (jl_sym_t*)jl_deserialize_value(s); li->specTypes = (jl_tuple_t*)jl_deserialize_value(s); li->specializations = (jl_array_t*)jl_deserialize_value(s); li->inferred = read_int8(s); li->file = jl_deserialize_value(s); li->line = read_int32(s); li->module = (jl_module_t*)jl_deserialize_value(s); li->roots = (jl_array_t*)jl_deserialize_value(s); li->def = (jl_lambda_info_t*)jl_deserialize_value(s); li->capt = jl_deserialize_value(s); li->fptr = &jl_trampoline; li->functionObject = NULL; li->cFunctionObject = NULL; li->inInference = 0; li->inCompile = 0; li->unspecialized = NULL; return (jl_value_t*)li; } else if (vtag == (jl_value_t*)jl_module_type) { jl_sym_t *mname = (jl_sym_t*)jl_deserialize_value(s); jl_module_t *m = jl_new_module(mname); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, m); m->parent = (jl_module_t*)jl_deserialize_value(s); while (1) { jl_value_t *name = jl_deserialize_value(s); if (name == NULL) break; jl_binding_t *b = jl_get_binding_wr(m, (jl_sym_t*)name); b->value = jl_deserialize_value(s); b->type = (jl_type_t*)jl_deserialize_value(s); b->owner = (jl_module_t*)jl_deserialize_value(s); int8_t flags = read_int8(s); b->constp = (flags>>2) & 1; b->exportp = (flags>>1) & 1; b->imported = (flags) & 1; } size_t ni = read_int32(s); for(size_t i=0; i < ni; i++) { arraylist_push(&m->usings, jl_deserialize_value(s)); } return (jl_value_t*)m; }