Exemplo n.º 1
0
DLLEXPORT void jl_show_any(jl_value_t *str, jl_value_t *v)
{
    ios_t *s = (ios_t*)jl_iostr_data(str);
    // fallback for printing some other builtin types
    if (jl_is_tuple(v)) {
        jl_show_tuple(str, (jl_tuple_t*)v, '(', ')', 1);
    }
    else if (jl_is_type(v)) {
        show_type(str, v);
    }
    else if (jl_is_func(v)) {
        show_function(s, v);
    }
    else if (jl_typeis(v,jl_intrinsic_type)) {
        JL_PRINTF(s, "#<intrinsic-function %d>", *(uint32_t*)jl_bits_data(v));
    }
    else {
        jl_value_t *t = (jl_value_t*)jl_typeof(v);
        assert(jl_is_struct_type(t) || jl_is_bits_type(t));
        jl_tag_type_t *tt = (jl_tag_type_t*)t;
        JL_PUTS(tt->name->name->name, s);
        if (tt->parameters != jl_null) {
            jl_show_tuple(str, tt->parameters, '{', '}', 0);
        }
        JL_PUTC('(', s);
        if (jl_is_struct_type(tt)) {
            jl_struct_type_t *st = (jl_struct_type_t*)tt;
            size_t i;
            size_t n = jl_tuple_len(st->names);
            for(i=0; i < n; i++) {
                jl_value_t *fval = jl_get_nth_field(v, i);
                if (fval == NULL)
                    JL_PUTS("#undef", s);
                else
                    jl_show(str, fval);
                if (i < n-1)
                    JL_PUTC(',', s);
            }
        }
        else {
            size_t nb = jl_bitstype_nbits(tt)/8;
            char *data = (char*)jl_bits_data(v);
            JL_PUTS("0x", s);
            for(int i=nb-1; i >= 0; --i)
                ios_printf(s, "%02hhx", data[i]);
        }
        JL_PUTC(')', s);
    }
}
Exemplo n.º 2
0
DLLEXPORT void jl_show_any(jl_value_t *v)
{
    // fallback for printing some other builtin types
    ios_t *s = jl_current_output_stream();
    if (jl_is_tuple(v)) {
        show_tuple((jl_tuple_t*)v, '(', ')', 1);
    }
    else if (jl_is_type(v)) {
        show_type(v);
    }
    else if (jl_is_func(v)) {
        show_function(v);
    }
    else if (jl_typeis(v,jl_intrinsic_type)) {
        ios_printf(s, "#<intrinsic-function %d>", *(uint32_t*)jl_bits_data(v));
    }
    else {
        jl_value_t *t = (jl_value_t*)jl_typeof(v);
        if (jl_is_struct_type(t)) {
            jl_struct_type_t *st = (jl_struct_type_t*)t;
            ios_puts(st->name->name->name, s);
            ios_putc('(', s);
            size_t i;
            size_t n = st->names->length;
            for(i=0; i < n; i++) {
                jl_show(nth_field(v, i));
                if (i < n-1)
                    ios_putc(',', s);
            }
            ios_putc(')', s);
        }
    }
}
Exemplo n.º 3
0
DLLEXPORT void jl_show_any(jl_value_t *str, jl_value_t *v)
{
    ios_t *s = (ios_t*)jl_iostr_data(str);
    // fallback for printing some other builtin types
    if (jl_is_tuple(v)) {
        jl_show_tuple(str, (jl_tuple_t*)v, '(', ')', 1);
    }
    else if (jl_is_type(v)) {
        show_type(str, v);
    }
    else if (jl_is_func(v)) {
        show_function(s, v);
    }
    else if (jl_typeis(v,jl_intrinsic_type)) {
        JL_PRINTF(s, "#<intrinsic-function %d>", *(uint32_t*)jl_bits_data(v));
    }
    else {
        jl_value_t *t = (jl_value_t*)jl_typeof(v);
        if (jl_is_struct_type(t)) {
            jl_struct_type_t *st = (jl_struct_type_t*)t;
            JL_PUTS(st->name->name->name, s);
            JL_PUTC('(', s);
            size_t i;
            size_t n = jl_tuple_len(st->names);
            for(i=0; i < n; i++) {
                jl_show(str, nth_field(v, i));
                if (i < n-1)
                    JL_PUTC(',', s);
            }
            JL_PUTC(')', s);
        }
    }
}
Exemplo n.º 4
0
// this is a run-time function
// warning: cannot allocate memory except using alloc_temp_arg_space
extern "C" void *jl_value_to_pointer(jl_value_t *jt, jl_value_t *v, int argn,
                                     int addressof)
{
    jl_value_t *jvt = (jl_value_t*)jl_typeof(v);
    if (addressof) {
        if (jvt == jt) {
            if (jl_is_bits_type(jvt)) {
                size_t osz = jl_bitstype_nbits(jt)/8;
                return alloc_temp_arg_copy(jl_bits_data(v), osz);
            } else if (jl_is_struct_type(jvt) && jl_is_leaf_type(jvt) && !jl_is_array_type(jvt)) {
                return v + 1;
            }
        }
        goto value_to_pointer_error;
    }
    else {
        if (jl_is_cpointer_type(jvt) && jl_tparam0(jvt) == jt) {
            return (void*)jl_unbox_voidpointer(v);
        }
    }

    if (((jl_value_t*)jl_uint8_type == jt ||
         (jl_value_t*)jl_int8_type == jt) && jl_is_byte_string(v)) {
        return jl_string_data(v);
    }
    if (jl_is_array_type(jvt)) {
        if (jl_tparam0(jl_typeof(v)) == jt || jt==(jl_value_t*)jl_bottom_type)
            return ((jl_array_t*)v)->data;
        if (jl_is_cpointer_type(jt)) {
            jl_array_t *ar = (jl_array_t*)v;
            void **temp=(void**)alloc_temp_arg_space(jl_array_len(ar)*sizeof(void*));
            size_t i;
            for(i=0; i < jl_array_len(ar); i++) {
                temp[i] = jl_value_to_pointer(jl_tparam0(jt),
                                              jl_arrayref(ar, i), argn, 0);
            }
            return temp;
        }
    }

 value_to_pointer_error:
    std::map<int, std::string>::iterator it = argNumberStrings.find(argn);
    if (it == argNumberStrings.end()) {
        std::stringstream msg;
        msg << "argument ";
        msg << argn;
        argNumberStrings[argn] = msg.str();
        it = argNumberStrings.find(argn);
    }
    jl_value_t *targ=NULL, *pty=NULL;
    JL_GC_PUSH(&targ, &pty);
    targ = (jl_value_t*)jl_tuple1(jt);
    pty = (jl_value_t*)jl_apply_type((jl_value_t*)jl_pointer_type,
                                     (jl_tuple_t*)targ);
    jl_type_error_rt("ccall", (*it).second.c_str(), pty, v);
    // doesn't return
    return (jl_value_t*)jl_null;
}
Exemplo n.º 5
0
Arquivo: repl.c Projeto: julienr/julia
static void repl_show_value(jl_value_t *v)
{
    if (jl_is_function(v) && !jl_is_struct_type(v)) {
        // show method table when a function is shown at the top level.
        jl_show_full_function(v);
        return;
    }
    jl_show(v);
    if (jl_is_struct_type(v)) {
        ios_t *s = jl_current_output_stream();
        // for convenience, show constructor methods when
        // a type is shown at the top level.
        if (jl_is_gf(v)) {
            ios_putc('\n', s);
            jl_show_full_function(v);
        }
    }
}
Exemplo n.º 6
0
Arquivo: gf.c Projeto: cshen/julia
static
jl_function_t *jl_method_cache_insert(jl_methtable_t *mt, jl_tuple_t *type,
                                      jl_function_t *method)
{
    jl_methlist_t **pml = &mt->cache;
    if (type->length > 0) {
        jl_value_t *t0 = jl_t0(type);
        uptrint_t uid=0;
        // if t0 != jl_typetype_type and the argument is Type{...}, this
        // method has specializations for singleton kinds and we use
        // the table indexed for that purpose.
        if (t0 != (jl_value_t*)jl_typetype_type && jl_is_type_type(t0)) {
            jl_value_t *a0 = jl_tparam0(t0);
            if (jl_is_struct_type(a0))
                uid = ((jl_struct_type_t*)a0)->uid;
            else if (jl_is_bits_type(a0))
                uid = ((jl_bits_type_t*)a0)->uid;
            if (uid > 0) {
                if (mt->cache_targ == NULL)
                    mt->cache_targ = jl_alloc_cell_1d(0);
                if (uid >= jl_array_len(mt->cache_targ)) {
                    jl_array_grow_end(mt->cache_targ, uid+4-jl_array_len(mt->cache_targ));
                }
                pml = (jl_methlist_t**)&jl_cellref(mt->cache_targ, uid);
                goto ml_do_insert;
            }
        }
        if (jl_is_struct_type(t0))
            uid = ((jl_struct_type_t*)t0)->uid;
        else if (jl_is_bits_type(t0))
            uid = ((jl_bits_type_t*)t0)->uid;
        if (uid > 0) {
            if (mt->cache_arg1 == NULL)
                mt->cache_arg1 = jl_alloc_cell_1d(0);
            if (uid >= jl_array_len(mt->cache_arg1)) {
                jl_array_grow_end(mt->cache_arg1, uid+4-jl_array_len(mt->cache_arg1));
            }
            pml = (jl_methlist_t**)&jl_cellref(mt->cache_arg1, uid);
        }
    }
 ml_do_insert:
    return jl_method_list_insert(pml, type, method, jl_null, 0)->func;
}
Exemplo n.º 7
0
Arquivo: gf.c Projeto: cshen/julia
static jl_function_t *jl_method_table_assoc_exact(jl_methtable_t *mt,
                                                  jl_value_t **args, size_t n)
{
    jl_methlist_t *ml = NULL;
    if (n > 0) {
        jl_value_t *a0 = args[0];
        jl_value_t *ty = (jl_value_t*)jl_typeof(a0);
        uptrint_t uid;
        if ((ty == (jl_value_t*)jl_struct_kind && (uid = ((jl_struct_type_t*)a0)->uid)) ||
            (ty == (jl_value_t*)jl_bits_kind   && (uid = ((jl_bits_type_t*)a0)->uid))) {
            if (mt->cache_targ &&
                uid < jl_array_len(mt->cache_targ)) {
                ml = (jl_methlist_t*)jl_cellref(mt->cache_targ, uid);
                if (ml)
                    goto mt_assoc_lkup;
            }
        }
        if ((jl_is_struct_type(ty) && (uid = ((jl_struct_type_t*)ty)->uid)) ||
            (jl_is_bits_type(ty)   && (uid = ((jl_bits_type_t*)ty)->uid))) {
            if (mt->cache_arg1 &&
                uid < jl_array_len(mt->cache_arg1)) {
                ml = (jl_methlist_t*)jl_cellref(mt->cache_arg1, uid);
                if (ml) {
                    if (ml->next==NULL && n==1 && ml->sig->length==1)
                        return ml->func;
                    if (n==2) {
                        // some manually-unrolled common special cases
                        jl_value_t *a1 = args[1];
                        jl_methlist_t *mn = ml;
                        if (mn->sig->length==2 &&
                            jl_tupleref(mn->sig,1)==(jl_value_t*)jl_typeof(a1))
                            return mn->func;
                        mn = mn->next;
                        if (mn && mn->sig->length==2 &&
                            jl_tupleref(mn->sig,1)==(jl_value_t*)jl_typeof(a1))
                            return mn->func;
                    }
                }
            }
        }
    }
    if (ml == NULL)
        ml = mt->cache;
 mt_assoc_lkup:
    while (ml != NULL) {
        if (((jl_tuple_t*)ml->sig)->length == n || ml->va==jl_true) {
            if (cache_match(args, n, (jl_tuple_t*)ml->sig, ml->va==jl_true)) {
                return ml->func;
            }
        }
        ml = ml->next;
    }
    return NULL;
}
Exemplo n.º 8
0
jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd,
                          jl_tuple_t *argtypes, jl_function_t *f, jl_tuple_t *t)
{
    jl_value_t *gf;
    if (bnd) {
        //jl_declare_constant(bnd);
        if (bnd->value != NULL && !bnd->constp) {
            jl_errorf("cannot define function %s; it already has a value",
                      bnd->name->name);
        }
        bnd->constp = 1;
    }
    if (*bp == NULL) {
        gf = (jl_value_t*)jl_new_generic_function(name);
        *bp = gf;
    }
    else {
        gf = *bp;
        if (!jl_is_gf(gf)) {
            if (jl_is_struct_type(gf) &&
                ((jl_function_t*)gf)->fptr == jl_f_ctor_trampoline) {
                jl_add_constructors((jl_struct_type_t*)gf);
            }
            if (!jl_is_gf(gf)) {
                jl_error("invalid method definition: not a generic function");
            }
        }
    }
    JL_GC_PUSH(&gf);
    assert(jl_is_function(f));
    assert(jl_is_tuple(argtypes));
    assert(jl_is_tuple(t));
    jl_check_type_tuple(argtypes, name, "method definition");
    for(size_t i=0; i < t->length; i++) {
        if (!jl_is_typevar(jl_tupleref(t,i)))
            jl_type_error_rt(name->name, "method definition",
                             (jl_value_t*)jl_tvar_type, jl_tupleref(t,i));
    }
    jl_add_method((jl_function_t*)gf, argtypes, f, t);
    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);
    }
    JL_GC_POP();
    return gf;
}
Exemplo n.º 9
0
static void jl_serialize_tag_type(ios_t *s, jl_value_t *v)
{
    if (jl_is_struct_type(v)) {
        writetag(s, (jl_value_t*)jl_struct_kind);
        jl_serialize_value(s, jl_struct_kind);
        write_uint16(s, jl_tuple_len(((jl_struct_type_t*)v)->names));
        write_int32(s, ((jl_struct_type_t*)v)->uid);
        write_int32(s, ((jl_struct_type_t*)v)->size);
        write_int32(s, ((jl_struct_type_t*)v)->alignment);
        size_t nf = jl_tuple_len(((jl_struct_type_t*)v)->names);
        ios_write(s, (char*)&((jl_struct_type_t*)v)->fields[0], nf*sizeof(jl_fielddesc_t));
        jl_serialize_value(s, ((jl_struct_type_t*)v)->name);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->parameters);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->super);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->names);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->types);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->ctor_factory);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->env);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->linfo);
        jl_serialize_fptr(s, ((jl_struct_type_t*)v)->fptr);
    }
    else if (jl_is_bits_type(v)) {
        writetag(s, jl_struct_kind);
        jl_serialize_value(s, jl_bits_kind);
        if (v == (jl_value_t*)jl_int32_type)
            write_uint8(s, 2);
        else if (v == (jl_value_t*)jl_bool_type)
            write_uint8(s, 3);
        else if (v == (jl_value_t*)jl_int64_type)
            write_uint8(s, 4);
        else
            write_uint8(s, 0);
        jl_serialize_value(s, ((jl_tag_type_t*)v)->name);
        jl_serialize_value(s, ((jl_bits_type_t*)v)->parameters);
        write_int32(s, ((jl_bits_type_t*)v)->nbits);
        jl_serialize_value(s, ((jl_bits_type_t*)v)->super);
        write_int32(s, ((jl_bits_type_t*)v)->uid);
    }
    else {
        assert(jl_is_tag_type(v));
        writetag(s, jl_tag_kind);
        jl_serialize_value(s, ((jl_tag_type_t*)v)->name);
        jl_serialize_value(s, ((jl_tag_type_t*)v)->parameters);
        jl_serialize_value(s, ((jl_tag_type_t*)v)->super);
    }
}
Exemplo n.º 10
0
DLLEXPORT uptrint_t jl_object_id(jl_value_t *v)
{
    if (jl_is_symbol(v))
        return ((jl_sym_t*)v)->hash;
    jl_value_t *tv = (jl_value_t*)jl_typeof(v);
    if (jl_is_bits_type(tv)) {
        size_t nb = jl_bitstype_nbits(tv)/8;
        uptrint_t h = inthash((uptrint_t)tv);
        switch (nb) {
        case 1:
            return int32hash(*(int8_t*)jl_bits_data(v) ^ h);
        case 2:
            return int32hash(*(int16_t*)jl_bits_data(v) ^ h);
        case 4:
            return int32hash(*(int32_t*)jl_bits_data(v) ^ h);
        case 8:
            return hash64(*(int64_t*)jl_bits_data(v) ^ h);
        default:
#ifdef __LP64__
            return h ^ memhash((char*)jl_bits_data(v), nb);
#else
            return h ^ memhash32((char*)jl_bits_data(v), nb);
#endif
        }
    }
    if (tv == (jl_value_t*)jl_union_kind) {
#ifdef __LP64__
        return jl_object_id(jl_fieldref(v,0))^0xA5A5A5A5A5A5A5A5L;
#else
        return jl_object_id(jl_fieldref(v,0))^0xA5A5A5A5;
#endif
    }
    if (jl_is_struct_type(tv))
        return inthash((uptrint_t)v);
    assert(jl_is_tuple(v));
    uptrint_t h = 0;
    size_t l = jl_tuple_len(v);
    for(size_t i = 0; i < l; i++) {
        uptrint_t u = jl_object_id(jl_tupleref(v,i));
        h = bitmix(h, u);
    }
    return h;
}
Exemplo n.º 11
0
static void jl_serialize_tag_type(ios_t *s, jl_value_t *v)
{
    if (jl_is_struct_type(v)) {
        writetag(s, (jl_value_t*)jl_struct_kind);
        jl_serialize_value(s, jl_struct_kind);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->name);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->parameters);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->super);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->names);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->types);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->ctor_factory);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->env);
        jl_serialize_value(s, ((jl_struct_type_t*)v)->linfo);
        jl_serialize_fptr(s, ((jl_struct_type_t*)v)->fptr);
        write_int32(s, ((jl_struct_type_t*)v)->uid);
    }
    else if (jl_is_bits_type(v)) {
        writetag(s, jl_struct_kind);
        jl_serialize_value(s, jl_bits_kind);
        if (v == (jl_value_t*)jl_int32_type)
            write_uint8(s, 2);
        else if (v == (jl_value_t*)jl_bool_type)
            write_uint8(s, 3);
        else if (v == (jl_value_t*)jl_int64_type)
            write_uint8(s, 4);
        else
            write_uint8(s, 0);
        jl_serialize_value(s, ((jl_tag_type_t*)v)->name);
        jl_serialize_value(s, ((jl_bits_type_t*)v)->parameters);
        write_int32(s, ((jl_bits_type_t*)v)->nbits);
        jl_serialize_value(s, ((jl_bits_type_t*)v)->super);
        write_int32(s, ((jl_bits_type_t*)v)->uid);
    }
    else {
        assert(jl_is_tag_type(v));
        writetag(s, jl_tag_kind);
        jl_serialize_value(s, ((jl_tag_type_t*)v)->name);
        jl_serialize_value(s, ((jl_tag_type_t*)v)->parameters);
        jl_serialize_value(s, ((jl_tag_type_t*)v)->super);
    }
}
Exemplo n.º 12
0
Arquivo: gf.c Projeto: cshen/julia
/*
  Method caches are divided into three parts: one for signatures where
  the first argument is a singleton kind (Type{Foo}), one indexed by the
  UID of the first argument's type in normal cases, and a fallback
  table of everything else.
*/
static jl_function_t *jl_method_table_assoc_exact_by_type(jl_methtable_t *mt,
                                                          jl_tuple_t *types)
{
    jl_methlist_t *ml = NULL;
    if (types->length > 0) {
        jl_value_t *ty = jl_t0(types);
        uptrint_t uid;
        if (jl_is_type_type(ty)) {
            jl_value_t *a0 = jl_tparam0(ty);
            jl_value_t *tty = (jl_value_t*)jl_typeof(a0);
            if ((tty == (jl_value_t*)jl_struct_kind && (uid = ((jl_struct_type_t*)a0)->uid)) ||
                (tty == (jl_value_t*)jl_bits_kind   && (uid = ((jl_bits_type_t*)a0)->uid))) {
                if (mt->cache_targ &&
                    uid < jl_array_len(mt->cache_targ)) {
                    ml = (jl_methlist_t*)jl_cellref(mt->cache_targ, uid);
                    if (ml)
                        goto mt_assoc_bt_lkup;
                }
            }
        }
        if ((jl_is_struct_type(ty) && (uid = ((jl_struct_type_t*)ty)->uid)) ||
            (jl_is_bits_type(ty)   && (uid = ((jl_bits_type_t*)ty)->uid))) {
            if (mt->cache_arg1 && uid < jl_array_len(mt->cache_arg1)) {
                ml = (jl_methlist_t*)jl_cellref(mt->cache_arg1, uid);
            }
        }
    }
    if (ml == NULL)
        ml = mt->cache;
 mt_assoc_bt_lkup:
    while (ml != NULL) {
        if (cache_match_by_type(&jl_tupleref(types,0), types->length,
                                (jl_tuple_t*)ml->sig, ml->va==jl_true)) {
            return ml->func;
        }
        ml = ml->next;
    }
    return NULL;
}
Exemplo n.º 13
0
jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd,
                          jl_tuple_t *argtypes, jl_function_t *f, jl_tuple_t *t)
{
    jl_value_t *gf;
    if (bnd) {
        jl_declare_constant(bnd);
    }
    if (*bp == NULL) {
        gf = (jl_value_t*)jl_new_generic_function(name);
        *bp = gf;
    }
    else {
        gf = *bp;
        if (!jl_is_gf(gf)) {
            if (jl_is_struct_type(gf) &&
                ((jl_function_t*)gf)->fptr == jl_f_ctor_trampoline) {
                jl_add_constructors((jl_struct_type_t*)gf);
            }
            if (!jl_is_gf(gf)) {
                jl_error("invalid method definition: not a generic function");
            }
        }
    }
    JL_GC_PUSH(&gf);
    assert(jl_is_function(f));
    assert(jl_is_tuple(argtypes));
    jl_check_type_tuple(argtypes, name, "method definition");
    jl_add_method((jl_function_t*)gf, argtypes, f, t);
    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);
    }
    JL_GC_POP();
    return gf;
}
Exemplo n.º 14
0
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_value_t *v = jl_get_global(jl_current_module,
                                      (jl_sym_t*)jl_fieldref(e,0));
        if (v == NULL)
            jl_errorf("%s not defined", ((jl_sym_t*)jl_fieldref(e,0))->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);
    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], ex->args->length-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_GC_PUSH(&thetype);
        assert(jl_is_struct_type(thetype));
        jl_value_t *v = jl_new_struct_uninit((jl_struct_type_t*)thetype);
        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;
        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 jl_nothing;
    }
    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 < ex->args->length; 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(&para, &super);
        jl_tag_type_t *tt=jl_new_tagtype(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*)tt);
        super = eval(args[2], locals, nl);
        jl_set_tag_type_super(tt, 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(&para, &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_bits_type_t *bt = jl_new_bits_type(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*)bt);
        super = eval(args[3], locals, nl);
        jl_set_tag_type_super((jl_tag_type_t*)bt, super);
        JL_GC_POP();
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == compositetype_sym) {
        void jl_add_constructors(jl_struct_type_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_struct_type_t *st = NULL;
        JL_GC_PUSH(&para, &super, &fnames, &st);
        fnames = eval(args[2], locals, nl);
        st = jl_new_struct_type((jl_sym_t*)name, jl_any_type, (jl_tuple_t*)para,
                                (jl_tuple_t*)fnames, NULL);
        st->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*)st);
        st->types = (jl_tuple_t*)eval(args[5], locals, nl);
        jl_check_type_tuple(st->types, st->name->name, "type definition");
        super = eval(args[4], locals, nl);
        jl_set_tag_type_super((jl_tag_type_t*)st, super);
        jl_compute_struct_offsets(st);
        jl_add_constructors(st);
        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 error: %s", jl_string_data(args[0]));
        jl_raise(args[0]);
    }
    jl_errorf("unsupported or misplaced expression %s", ex->head->name);
    return (jl_value_t*)jl_nothing;
}
Exemplo n.º 15
0
static Value *julia_to_native(Type *ty, jl_value_t *jt, Value *jv,
                              jl_value_t *argex, bool addressOf,
                              int argn, jl_codectx_t *ctx)
{
    Type *vt = jv->getType();
    if (ty == jl_pvalue_llvmt) {
        return boxed(jv);
    }
    else if (ty == vt && !addressOf) {
        return jv;
    }
    else if (vt != jl_pvalue_llvmt) {
        // argument value is unboxed
        if (addressOf) {
            if (ty->isPointerTy() && ty->getContainedType(0)==vt) {
                // pass the address of an alloca'd thing, not a box
                // since those are immutable.
                Value *slot = builder.CreateAlloca(vt);
                builder.CreateStore(jv, slot);
                return builder.CreateBitCast(slot, ty);
            }
        }
        else if ((vt->isIntegerTy() && ty->isIntegerTy()) ||
                 (vt->isFloatingPointTy() && ty->isFloatingPointTy()) ||
                 (vt->isPointerTy() && ty->isPointerTy())) {
            if (vt->getPrimitiveSizeInBits() ==
                ty->getPrimitiveSizeInBits()) {
                return builder.CreateBitCast(jv, ty);
            }
        }
        // error. box for error handling.
        jv = boxed(jv);
    }
    else if (jl_is_cpointer_type(jt)) {
        assert(ty->isPointerTy());
        jl_value_t *aty = expr_type(argex, ctx);
        if (jl_is_array_type(aty) &&
            (jl_tparam0(jt) == jl_tparam0(aty) ||
             jl_tparam0(jt) == (jl_value_t*)jl_bottom_type)) {
            // array to pointer
            return builder.CreateBitCast(emit_arrayptr(jv), ty);
        }
        if (aty == (jl_value_t*)jl_ascii_string_type || aty == (jl_value_t*)jl_utf8_string_type) {
            return builder.CreateBitCast(emit_arrayptr(emit_nthptr(jv,1)), ty);
        }
        if (jl_is_struct_type(aty) && jl_is_leaf_type(aty) && !jl_is_array_type(aty)) {
            if (!addressOf) {
                emit_error("ccall: expected addressOf operator", ctx);
                return literal_pointer_val(jl_nothing);
            }
            return builder.CreateBitCast(emit_nthptr_addr(jv, (size_t)1), ty); // skip type tag field
        }
        Value *p = builder.CreateCall4(value_to_pointer_func,
                                       literal_pointer_val(jl_tparam0(jt)), jv,
                                       ConstantInt::get(T_int32, argn),
                                       ConstantInt::get(T_int32, (int)addressOf));
        return builder.CreateBitCast(p, ty);
    }
    else if (jl_is_struct_type(jt)) {
        if (addressOf)
            jl_error("ccall: unexpected addressOf operator"); // the only "safe" thing to emit here is the expected struct
        assert (ty->isStructTy() && (Type*)((jl_struct_type_t*)jt)->struct_decl == ty);
        jl_value_t *aty = expr_type(argex, ctx);
        if (aty != jt) {
            std::stringstream msg;
            msg << "ccall argument ";
            msg << argn;
            emit_typecheck(jv, jt, msg.str(), ctx);
        }
        //TODO: check instead that prefix matches
        //if (!jl_is_struct_type(aty))
        //    emit_typecheck(emit_typeof(jv), (jl_value_t*)jl_struct_kind, "ccall: Struct argument called with something that isn't a CompositeKind", ctx);
        // //safe thing would be to also check that jl_typeof(aty)->size > sizeof(ty) here and/or at runtime
        Value *pjv = builder.CreateBitCast(emit_nthptr_addr(jv, (size_t)1), PointerType::get(ty,0));
        return builder.CreateLoad(pjv, false);
    }
    // TODO: error for & with non-pointer argument type
    assert(jl_is_bits_type(jt));
    std::stringstream msg;
    msg << "ccall argument ";
    msg << argn;
    emit_typecheck(jv, jt, msg.str(), ctx);
    Value *p = bitstype_pointer(jv);
    return builder.CreateLoad(builder.CreateBitCast(p,
                                                    PointerType::get(ty,0)),
                              false);
}
Exemplo n.º 16
0
// ccall(pointer, rettype, (argtypes...), args...)
static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
{
    JL_NARGSV(ccall, 3);
    jl_value_t *ptr=NULL, *rt=NULL, *at=NULL;
    Value *jl_ptr=NULL;
    JL_GC_PUSH(&ptr, &rt, &at);
    ptr = static_eval(args[1], ctx, true);
    if (ptr == NULL) {
        jl_value_t *ptr_ty = expr_type(args[1], ctx);
        Value *arg1 = emit_unboxed(args[1], ctx);
        if (!jl_is_cpointer_type(ptr_ty)) {
            emit_cpointercheck(arg1, 
                    "ccall: function argument not a pointer or valid, constant expression", ctx);
        }
        jl_ptr = emit_unbox(T_size, T_psize, arg1);
    }
    rt  = jl_interpret_toplevel_expr_in(ctx->module, args[2],
                                        &jl_tupleref(ctx->sp,0),
                                        jl_tuple_len(ctx->sp)/2);
    if (jl_is_tuple(rt)) {
        std::string msg = "in " + ctx->funcName +
            ": ccall: missing return type";
        jl_error(msg.c_str());
    }
    at  = jl_interpret_toplevel_expr_in(ctx->module, args[3],
                                        &jl_tupleref(ctx->sp,0),
                                        jl_tuple_len(ctx->sp)/2);
    void *fptr=NULL;
    char *f_name=NULL, *f_lib=NULL;
    if (ptr != NULL) {
        if (jl_is_tuple(ptr) && jl_tuple_len(ptr)==1) {
            ptr = jl_tupleref(ptr,0);
        }
        if (jl_is_symbol(ptr))
            f_name = ((jl_sym_t*)ptr)->name;
        else if (jl_is_byte_string(ptr))
            f_name = jl_string_data(ptr);
        if (f_name != NULL) {
            // just symbol, default to JuliaDLHandle
#ifdef __WIN32__
         //TODO: store the f_lib name instead of fptr
        fptr = jl_dlsym_win32(f_name);
#else
            // will look in process symbol table
#endif
        }
        else if (jl_is_cpointer_type(jl_typeof(ptr))) {
            fptr = *(void**)jl_bits_data(ptr);
        }
        else if (jl_is_tuple(ptr) && jl_tuple_len(ptr)>1) {
            jl_value_t *t0 = jl_tupleref(ptr,0);
            jl_value_t *t1 = jl_tupleref(ptr,1);
            if (jl_is_symbol(t0))
                f_name = ((jl_sym_t*)t0)->name;
            else if (jl_is_byte_string(t0))
                f_name = jl_string_data(t0);
            else
                JL_TYPECHK(ccall, symbol, t0);
            if (jl_is_symbol(t1))
                f_lib = ((jl_sym_t*)t1)->name;
            else if (jl_is_byte_string(t1))
                f_lib = jl_string_data(t1);
            else
                JL_TYPECHK(ccall, symbol, t1);
        }
        else {
            JL_TYPECHK(ccall, pointer, ptr);
        }
    }
    if (f_name == NULL && fptr == NULL && jl_ptr == NULL) {
        JL_GC_POP();
        emit_error("ccall: null function pointer", ctx);
        return literal_pointer_val(jl_nothing);
    }

    JL_TYPECHK(ccall, type, rt);
    JL_TYPECHK(ccall, tuple, at);
    JL_TYPECHK(ccall, type, at);
    jl_tuple_t *tt = (jl_tuple_t*)at;
    std::vector<Type *> fargt(0);
    std::vector<Type *> fargt_sig(0);
    Type *lrt = julia_struct_to_llvm(rt);
    if (lrt == NULL) {
        JL_GC_POP();
        emit_error("ccall: return type doesn't correspond to a C type", ctx);
        return literal_pointer_val(jl_nothing);
    }
    size_t i;
    bool haspointers = false;
    bool isVa = false;
    size_t nargt = jl_tuple_len(tt);
    std::vector<AttributeWithIndex> attrs;

    for(i=0; i < nargt; i++) {
        jl_value_t *tti = jl_tupleref(tt,i);
        if (jl_is_vararg_type(tti)) {
            isVa = true;
            tti = jl_tparam0(tti);
        }
        if (jl_is_bits_type(tti)) {
            // see pull req #978. need to annotate signext/zeroext for
            // small integer arguments.
            jl_bits_type_t *bt = (jl_bits_type_t*)tti;
            if (bt->nbits < 32) {
                if (jl_signed_type == NULL) {
                    jl_signed_type = jl_get_global(jl_core_module,jl_symbol("Signed"));
                }
#ifdef LLVM32
                Attributes::AttrVal av;
                if (jl_signed_type && jl_subtype(tti, jl_signed_type, 0))
                    av = Attributes::SExt;
                else
                    av = Attributes::ZExt;
                attrs.push_back(AttributeWithIndex::get(getGlobalContext(), i+1,
                                                        ArrayRef<Attributes::AttrVal>(&av, 1)));
#else
                Attribute::AttrConst av;
                if (jl_signed_type && jl_subtype(tti, jl_signed_type, 0))
                    av = Attribute::SExt;
                else
                    av = Attribute::ZExt;
                attrs.push_back(AttributeWithIndex::get(i+1, av));
#endif
            }
        }
        Type *t = julia_struct_to_llvm(tti);
        if (t == NULL) {
            JL_GC_POP();
            std::stringstream msg;
            msg << "ccall: the type of argument ";
            msg << i+1;
            msg << " doesn't correspond to a C type containing only BitsKinds";
            emit_error(msg.str(), ctx);
            return literal_pointer_val(jl_nothing);
        }
        fargt.push_back(t);
        if (!isVa)
            fargt_sig.push_back(t);
    }
    // check for calling convention specifier
    CallingConv::ID cc = CallingConv::C;
    jl_value_t *last = args[nargs];
    if (jl_is_expr(last)) {
        jl_sym_t *lhd = ((jl_expr_t*)last)->head;
        if (lhd == jl_symbol("stdcall")) {
            cc = CallingConv::X86_StdCall;
            nargs--;
        }
        else if (lhd == jl_symbol("cdecl")) {
            cc = CallingConv::C;
            nargs--;
        }
        else if (lhd == jl_symbol("fastcall")) {
            cc = CallingConv::X86_FastCall;
            nargs--;
        }
        else if (lhd == jl_symbol("thiscall")) {
            cc = CallingConv::X86_ThisCall;
            nargs--;
        }
    }
    
    if ((!isVa && jl_tuple_len(tt)  != (nargs-2)/2) ||
        ( isVa && jl_tuple_len(tt)-1 > (nargs-2)/2))
        jl_error("ccall: wrong number of arguments to C function");

    // some special functions
    if (fptr == &jl_array_ptr) {
        assert(lrt->isPointerTy());
        Value *ary = emit_expr(args[4], ctx);
        JL_GC_POP();
        return mark_julia_type(builder.CreateBitCast(emit_arrayptr(ary),lrt),
                               rt);
    }
    if (fptr == &jl_value_ptr) {
        assert(lrt->isPointerTy());
        Value *ary = emit_expr(args[4], ctx);
        JL_GC_POP();
        return mark_julia_type(builder.CreateBitCast(ary,lrt),rt);
    }

    // see if there are & arguments
    for(i=4; i < nargs+1; i+=2) {
        jl_value_t *argi = args[i];
        if (jl_is_expr(argi) && ((jl_expr_t*)argi)->head == amp_sym) {
            haspointers = true;
            break;
        }
    }

    // make LLVM function object for the target
    Value *llvmf;
    FunctionType *functype = FunctionType::get(lrt, fargt_sig, isVa);
    
    if (jl_ptr != NULL) {
        null_pointer_check(jl_ptr,ctx);
        Type *funcptype = PointerType::get(functype,0);
        llvmf = builder.CreateIntToPtr(jl_ptr, funcptype);
    } else if (fptr != NULL) {
        Type *funcptype = PointerType::get(functype,0);
        llvmf = literal_pointer_val(fptr, funcptype);
    }
    else {
        void *symaddr;
        if (f_lib != NULL)
            symaddr = add_library_sym(f_name, f_lib);
        else
            symaddr = sys::DynamicLibrary::SearchForAddressOfSymbol(f_name);
        if (symaddr == NULL) {
            JL_GC_POP();
            std::stringstream msg;
            msg << "ccall: could not find function ";
            msg << f_name;
            if (f_lib != NULL) {
                msg << " in library ";
                msg << f_lib;
            }
            emit_error(msg.str(), ctx);
            return literal_pointer_val(jl_nothing);
        }
        llvmf = jl_Module->getOrInsertFunction(f_name, functype);
    }

    // save temp argument area stack pointer
    Value *saveloc=NULL;
    Value *stacksave=NULL;
    if (haspointers) {
        // TODO: inline this
        saveloc = builder.CreateCall(save_arg_area_loc_func);
        stacksave =
            builder.CreateCall(Intrinsic::getDeclaration(jl_Module,
                                                         Intrinsic::stacksave));
    }

    // emit arguments
    Value *argvals[(nargs-3)/2];
    int last_depth = ctx->argDepth;
    int nargty = jl_tuple_len(tt);
    for(i=4; i < nargs+1; i+=2) {
        int ai = (i-4)/2;
        jl_value_t *argi = args[i];
        bool addressOf = false;
        if (jl_is_expr(argi) && ((jl_expr_t*)argi)->head == amp_sym) {
            addressOf = true;
            argi = jl_exprarg(argi,0);
        }
        Type *largty;
        jl_value_t *jargty;
        if (isVa && ai >= nargty-1) {
            largty = fargt[nargty-1];
            jargty = jl_tparam0(jl_tupleref(tt,nargty-1));
        }
        else {
            largty = fargt[ai];
            jargty = jl_tupleref(tt,ai);
        }
        Value *arg;
        if (largty == jl_pvalue_llvmt ||
                largty->isStructTy()) {
            arg = emit_expr(argi, ctx, true);
        }
        else {
            arg = emit_unboxed(argi, ctx);
            if (jl_is_bits_type(expr_type(argi, ctx))) {
                if (addressOf)
                    arg = emit_unbox(largty->getContainedType(0), largty, arg);
                else
                    arg = emit_unbox(largty, PointerType::get(largty,0), arg);
            }
        }
        /*
#ifdef JL_GC_MARKSWEEP
        // make sure args are rooted
        if (largty->isPointerTy() &&
            (largty == jl_pvalue_llvmt ||
             !jl_is_bits_type(expr_type(args[i], ctx)))) {
            make_gcroot(boxed(arg), ctx);
        }
#endif
        */
        argvals[ai] = julia_to_native(largty, jargty, arg, argi, addressOf,
                                      ai+1, ctx);
    }
    // the actual call
    Value *result = builder.CreateCall(llvmf,
                                       ArrayRef<Value*>(&argvals[0],(nargs-3)/2));
    if (cc != CallingConv::C)
        ((CallInst*)result)->setCallingConv(cc);

#ifdef LLVM32
    ((CallInst*)result)->setAttributes(AttrListPtr::get(getGlobalContext(), ArrayRef<AttributeWithIndex>(attrs)));
#else
    ((CallInst*)result)->setAttributes(AttrListPtr::get(attrs.data(),attrs.size()));
#endif
    // restore temp argument area stack pointer
    if (haspointers) {
        assert(saveloc != NULL);
        builder.CreateCall(restore_arg_area_loc_func, saveloc);
        assert(stacksave != NULL);
        builder.CreateCall(Intrinsic::getDeclaration(jl_Module,
                                                     Intrinsic::stackrestore),
                           stacksave);
    }
    ctx->argDepth = last_depth;
    if (0) { // Enable this to turn on SSPREQ (-fstack-protector) on the function containing this ccall
#ifdef LLVM32        
        ctx->f->addFnAttr(Attributes::StackProtectReq);
#else
        ctx->f->addFnAttr(Attribute::StackProtectReq);
#endif
    }

    JL_GC_POP();
    if (lrt == T_void)
        return literal_pointer_val((jl_value_t*)jl_nothing);
    if (lrt->isStructTy()) {
        //fprintf(stderr, "ccall rt: %s -> %s\n", f_name, ((jl_tag_type_t*)rt)->name->name->name);
        assert(jl_is_struct_type(rt));
        Value *strct =
            builder.CreateCall(jlallocobj_func,
                               ConstantInt::get(T_size,
                                    sizeof(void*)+((jl_struct_type_t*)rt)->size));
        builder.CreateStore(literal_pointer_val((jl_value_t*)rt),
                            emit_nthptr_addr(strct, (size_t)0));
        builder.CreateStore(result,
                            builder.CreateBitCast(
                                emit_nthptr_addr(strct, (size_t)1),
                                PointerType::get(lrt,0)));
        return mark_julia_type(strct, rt);
    }
    return mark_julia_type(result, rt);
}
Exemplo n.º 17
0
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_value_t *v = jl_get_global(jl_current_module,
                                      (jl_sym_t*)jl_fieldref(e,0));
        if (v == NULL)
            jl_errorf("%s not defined", ((jl_sym_t*)jl_fieldref(e,0))->name);
        return v;
    }
    if (!jl_is_expr(e)) {
        if (jl_is_lambda_info(e)) {
            return jl_new_closure_internal((jl_lambda_info_t*)e,
                                           (jl_value_t*)jl_null);
        }
        return e;
    }
    jl_expr_t *ex = (jl_expr_t*)e;
    jl_value_t **args = &jl_cellref(ex->args,0);
    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], ex->args->length-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_GC_PUSH(&thetype);
        assert(jl_is_struct_type(thetype));
        jl_value_t *v = jl_new_struct_uninit((jl_struct_type_t*)thetype);
        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;
        size_t i;
        for (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_wr(jl_current_module, fname);
            bp = &b->value;
        }
        jl_value_t *atypes=NULL, *meth=NULL;
        JL_GC_PUSH(&atypes, &meth);
        atypes = eval(args[1], locals, nl);
        meth = eval(args[2], locals, nl);
        jl_value_t *gf = jl_method_def(fname, bp, b, (jl_tuple_t*)atypes,
                                       (jl_function_t*)meth);
        JL_GC_POP();
        return gf;
    }
    else if (ex->head == const_sym) {
        jl_value_t *sym = args[0];
        size_t i;
        for (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 == error_sym) {
        jl_errorf("syntax error: %s", jl_string_data(args[0]));
    }
    else if (ex->head == line_sym) {
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == multivalue_sym) {
        return (jl_value_t*)jl_nothing;
    }
    jl_error("not supported");
    return (jl_value_t*)jl_nothing;
}
Exemplo n.º 18
0
static void jl_serialize_value_(ios_t *s, jl_value_t *v)
{
    if (v == NULL) {
        write_uint8(s, Null_tag);
        return;
    }

    void **bp = ptrhash_bp(&ser_tag, v);
    if (*bp != HT_NOTFOUND) {
        write_as_tag(s, (uint8_t)(ptrint_t)*bp);
        return;
    }

    if (tree_literal_values) {
        // compressing tree
        if (!is_ast_node(v)) {
            writetag(s, (jl_value_t*)LiteralVal_tag);
            write_uint16(s, literal_val_id(v));
            return;
        }
    }
    else {
        bp = ptrhash_bp(&backref_table, v);
        if (*bp != HT_NOTFOUND) {
            write_uint8(s, BackRef_tag);
            write_int32(s, (ptrint_t)*bp);
            return;
        }
        ptrhash_put(&backref_table, v, (void*)(ptrint_t)ios_pos(s));
    }

    size_t i;
    if (jl_is_tuple(v)) {
        size_t l = ((jl_tuple_t*)v)->length;
        if (l <= 255) {
            writetag(s, jl_tuple_type);
            write_uint8(s, (uint8_t)l);
        }
        else {
            writetag(s, (jl_value_t*)LongTuple_tag);
            write_int32(s, l);
        }
        for(i=0; i < l; i++) {
            jl_serialize_value(s, jl_tupleref(v, i));
        }
    }
    else if (jl_is_symbol(v)) {
        size_t l = strlen(((jl_sym_t*)v)->name);
        if (l <= 255) {
            writetag(s, jl_symbol_type);
            write_uint8(s, (uint8_t)l);
        }
        else {
            writetag(s, (jl_value_t*)LongSymbol_tag);
            write_int32(s, l);
        }
        ios_write(s, ((jl_sym_t*)v)->name, l);
    }
    else if (jl_is_array(v)) {
        jl_array_t *ar = (jl_array_t*)v;
        writetag(s, (jl_value_t*)jl_array_type);
        jl_serialize_value(s, ar->type);
        jl_value_t *elty = jl_tparam0(ar->type);
        for (i=0; i < ar->ndims; i++)
            jl_serialize_value(s, jl_box_long(jl_array_dim(ar,i)));
        if (jl_is_bits_type(elty)) {
            size_t tot = ar->length * ar->elsize;
            ios_write(s, ar->data, tot);
        }
        else {
            for(i=0; i < ar->length; i++) {
                jl_serialize_value(s, jl_cellref(v, i));
            }
        }
    }
    else if (jl_is_expr(v)) {
        jl_expr_t *e = (jl_expr_t*)v;
        size_t l = e->args->length;
        if (l <= 255) {
            writetag(s, jl_expr_type);
            write_uint8(s, (uint8_t)l);
        }
        else {
            writetag(s, (jl_value_t*)LongExpr_tag);
            write_int32(s, l);
        }
        jl_serialize_value(s, e->head);
        jl_serialize_value(s, e->etype);
        for(i=0; i < l; i++) {
            jl_serialize_value(s, jl_exprarg(e, i));
        }
    }
    else if (jl_is_some_tag_type(v)) {
        jl_serialize_tag_type(s, v);
    }
    else if (jl_is_typevar(v)) {
        writetag(s, jl_tvar_type);
        jl_serialize_value(s, ((jl_tvar_t*)v)->name);
        jl_serialize_value(s, ((jl_tvar_t*)v)->lb);
        jl_serialize_value(s, ((jl_tvar_t*)v)->ub);
        write_int8(s, ((jl_tvar_t*)v)->bound);
    }
    else if (jl_is_function(v)) {
        writetag(s, jl_func_kind);
        jl_serialize_value(s, v->type);
        jl_function_t *f = (jl_function_t*)v;
        jl_serialize_value(s, (jl_value_t*)f->linfo);
        jl_serialize_value(s, f->env);
        if (f->linfo && f->linfo->ast &&
            (jl_is_expr(f->linfo->ast) || jl_is_tuple(f->linfo->ast)) &&
            f->fptr != &jl_trampoline) {
            write_int32(s, 0);
        }
        else {
            jl_serialize_fptr(s, f->fptr);
        }
    }
    else if (jl_is_lambda_info(v)) {
        writetag(s, jl_lambda_info_type);
        jl_lambda_info_t *li = (jl_lambda_info_t*)v;
        jl_serialize_value(s, li->ast);
        jl_serialize_value(s, (jl_value_t*)li->sparams);
        // don't save cached type info for code in the Base module, because
        // it might reference types in the old System module.
        if (li->module == jl_base_module)
            jl_serialize_value(s, (jl_value_t*)jl_null);
        else
            jl_serialize_value(s, (jl_value_t*)li->tfunc);
        jl_serialize_value(s, (jl_value_t*)li->name);
        jl_serialize_value(s, (jl_value_t*)li->specTypes);
        jl_serialize_value(s, (jl_value_t*)li->specializations);
        jl_serialize_value(s, (jl_value_t*)li->inferred);
        jl_serialize_value(s, (jl_value_t*)li->file);
        jl_serialize_value(s, (jl_value_t*)li->line);
        jl_serialize_value(s, (jl_value_t*)li->module);
    }
    else if (jl_typeis(v, jl_module_type)) {
        jl_serialize_module(s, (jl_module_t*)v);
    }
    else if (jl_typeis(v, jl_methtable_type)) {
        writetag(s, jl_methtable_type);
        jl_methtable_t *mt = (jl_methtable_t*)v;
        jl_serialize_methlist(s, mt->defs);
        jl_serialize_methlist(s, mt->cache);
        jl_serialize_value(s, mt->cache_1arg);
        write_int32(s, mt->max_args);
    }
    else if (jl_typeis(v, jl_task_type)) {
        jl_error("Task cannot be serialized");
    }
    else {
        jl_value_t *t = (jl_value_t*)jl_typeof(v);
        if (jl_is_bits_type(t)) {
            void *data = jl_bits_data(v);
            if (t == (jl_value_t*)jl_int64_type &&
                *(int64_t*)data >= S32_MIN && *(int64_t*)data <= S32_MAX) {
                writetag(s, (jl_value_t*)SmallInt64_tag);
                write_int32(s, (int32_t)*(int64_t*)data);
            }
            else {
                int nb = ((jl_bits_type_t*)t)->nbits;
                writetag(s, jl_bits_kind);
                jl_serialize_value(s, t);
                ios_write(s, data, nb/8);
            }
        }
        else if (jl_is_struct_type(t)) {
            writetag(s, jl_struct_kind);
            jl_serialize_value(s, t);
            size_t nf = ((jl_struct_type_t*)t)->names->length;
            size_t i;
            for(i=0; i < nf; i++) {
                jl_value_t *fld = ((jl_value_t**)v)[i+1];
                jl_serialize_value(s, fld);
            }
            if (t == jl_idtable_type) {
                jl_cell_1d_push(idtable_list, v);
            }
        }
        else {
            assert(0);
        }
    }
}
Exemplo n.º 19
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);
}