Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
    }