Esempio n. 1
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));
    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;
}
Esempio n. 2
0
uv_buf_t jl_alloc_buf(uv_handle_t *handle, size_t suggested_size)
{
    uv_buf_t buf;
    JULIA_CB(alloc_buf,handle->data,1,CB_INT32,suggested_size);
    if (!jl_is_tuple(ret) || !jl_is_pointer(jl_t0(ret)) || !jl_is_int32(jl_t1(ret))) {
        jl_error("jl_alloc_buf: Julia function returned invalid value for buffer allocation callback");
    }
    buf.base = jl_unbox_voidpointer(jl_t0(ret));
    buf.len = jl_unbox_int32(jl_t1(ret));
    return buf;
}
Esempio n. 3
0
static inline int is_ntuple_long(jl_value_t *v)
{
    if (!jl_is_tuple(v))
        return 0;
    size_t nfields = jl_nfields(v);
    for (size_t i = 0; i < nfields; i++) {
        if (jl_field_type(jl_typeof(v), i) != (jl_value_t*)jl_long_type) {
            return 0;
        }
    }
    return 1;
}
Esempio n. 4
0
File: jl_uv.c Progetto: Lanzaa/julia
DLLEXPORT void jl_uv_alloc_buf(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf)
{
    if (handle->data) {
        JULIA_CB(alloc_buf,handle->data,1,CB_INT32,suggested_size);
        assert(jl_is_tuple(ret) && jl_is_pointer(jl_t0(ret)) && jl_is_int32(jl_t1(ret)));
        buf->base = (char*)jl_unbox_voidpointer(jl_t0(ret));
        buf->len = jl_unbox_int32(jl_t1(ret));
    }
    else {
        buf->len = 0;
    }
}
Esempio n. 5
0
File: gf.c Progetto: cshen/julia
static inline int cache_match(jl_value_t **args, size_t n, jl_tuple_t *sig,
                              int va)
{
    if (sig->length > n) {
        if (n != sig->length-1)
            return 0;
    }
    size_t i;
    for(i=0; i < n; i++) {
        jl_value_t *decl = jl_tupleref(sig, i);
        if (i == sig->length-1) {
            if (va) {
                jl_value_t *t = jl_tparam0(decl);
                for(; i < n; i++) {
                    if (!jl_subtype(args[i], t, 1))
                        return 0;
                }
                return 1;
            }
        }
        jl_value_t *a = args[i];
        if (jl_is_tuple(decl)) {
            // tuples don't have to match exactly, to avoid caching
            // signatures for tuples of every length
            if (!jl_subtype(a, decl, 1))
                return 0;
        }
        else if (jl_is_type_type(decl) &&
                 jl_is_nontuple_type(a)) {   //***
            if (jl_tparam0(decl) == (jl_value_t*)jl_typetype_tvar) {
                // in the case of Type{T}, the types don't have
                // to match exactly either. this is cached as Type{T}.
                // analogous to the situation with tuples.
            }
            else {
                if (a!=jl_tparam0(decl) && !jl_types_equal(a,jl_tparam0(decl)))
                    return 0;
            }
        }
        else if (decl == (jl_value_t*)jl_any_type) {
        }
        else {
            /*
              we know there are only concrete types here, and types are
              hash-consed, so pointer comparison should work.
            */
            if ((jl_value_t*)jl_typeof(a) != decl)
                return 0;
        }
    }
    return 1;
}
Esempio n. 6
0
File: gf.c Progetto: cshen/julia
static int cache_match_by_type(jl_value_t **types, size_t n, jl_tuple_t *sig,
                               int va)
{
    if (!va && n > sig->length)
        return 0;
    if (sig->length > n) {
        if (!(n == sig->length-1 && va))
            return 0;
    }
    size_t i;
    for(i=0; i < n; i++) {
        jl_value_t *decl = jl_tupleref(sig, i);
        if (i == sig->length-1) {
            if (va) {
                jl_value_t *t = jl_tparam0(decl);
                for(; i < n; i++) {
                    if (!jl_subtype(types[i], t, 0))
                        return 0;
                }
                return 1;
            }
        }
        jl_value_t *a = types[i];
        if (jl_is_tuple(decl)) {
            // tuples don't have to match exactly, to avoid caching
            // signatures for tuples of every length
            if (!jl_subtype(a, decl, 0))
                return 0;
        }
        else if (jl_is_tag_type(a) && jl_is_tag_type(decl) &&
                 ((jl_tag_type_t*)decl)->name == jl_type_type->name &&
                 ((jl_tag_type_t*)a   )->name == jl_type_type->name) {
            if (jl_tparam0(decl) == (jl_value_t*)jl_typetype_tvar) {
                // in the case of Type{T}, the types don't have
                // to match exactly either. this is cached as Type{T}.
                // analogous to the situation with tuples.
            }
            else {
                if (!jl_types_equal(jl_tparam0(a), jl_tparam0(decl))) {
                    return 0;
                }
            }
        }
        else if (decl == (jl_value_t*)jl_any_type) {
        }
        else {
            if (!jl_types_equal(a, decl))
                return 0;
        }
    }
    return 1;
}
Esempio n. 7
0
jl_typemap_entry_t *jl_typemap_assoc_exact(union jl_typemap_t ml_or_cache, jl_value_t **args, size_t n, int8_t offs)
{
    // NOTE: This function is a huge performance hot spot!!
    if (jl_typeof(ml_or_cache.unknown) == (jl_value_t*)jl_typemap_level_type) {
        jl_typemap_level_t *cache = ml_or_cache.node;
        if (n > offs) {
            jl_value_t *a1 = args[offs];
            jl_value_t *ty = (jl_value_t*)jl_typeof(a1);
            assert(jl_is_datatype(ty));
            if (ty == (jl_value_t*)jl_datatype_type && cache->targ != (void*)jl_nothing) {
                ml_or_cache = mtcache_hash_lookup(cache->targ, a1, 1, offs);
                jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, args, n, offs+1);
                if (ml) return ml;
            }
            if (cache->arg1 != (void*)jl_nothing) {
                ml_or_cache = mtcache_hash_lookup(cache->arg1, ty, 0, offs);
                if (jl_typeof(ml_or_cache.unknown) == (jl_value_t*)jl_typemap_entry_type &&
                        ml_or_cache.leaf->simplesig == (void*)jl_nothing && offs < 2 && n > 1) {
                    jl_value_t *a0 = args[1-offs];
                    jl_value_t *t0 = (jl_value_t*)jl_typeof(a0);
                    if (ml_or_cache.leaf->next==(void*)jl_nothing && n==2 && jl_datatype_nfields(ml_or_cache.leaf->sig)==2 &&
                        jl_tparam(ml_or_cache.leaf->sig, 1 - offs) == t0)
                        return ml_or_cache.leaf;
                    if (n==3) {
                        // some manually-unrolled common special cases
                        jl_value_t *a2 = args[2];
                        if (!jl_is_tuple(a2)) {  // issue #6426
                            jl_typemap_entry_t *mn = ml_or_cache.leaf;
                            if (jl_datatype_nfields(mn->sig)==3 &&
                                jl_tparam(mn->sig,1-offs)==t0 &&
                                jl_tparam(mn->sig,2)==(jl_value_t*)jl_typeof(a2))
                                return mn;
                            mn = mn->next;
                            if (mn!=(void*)jl_nothing && jl_datatype_nfields(mn->sig)==3 &&
                                jl_tparam(mn->sig,1-offs)==t0 &&
                                jl_tparam(mn->sig,2)==(jl_value_t*)jl_typeof(a2))
                                return mn;
                        }
                    }
                }
                jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, args, n, offs+1);
                if (ml) return ml;
            }
        }
        jl_typemap_entry_t *ml = jl_typemap_node_assoc_exact(cache->linear, args, n);
        if (ml) return ml;
        return jl_typemap_assoc_exact(cache->any, args, n, offs+1);
    }
    else {
        return jl_typemap_node_assoc_exact(ml_or_cache.leaf, args, n);
    }
}
Esempio n. 8
0
static size_t jl_new_bits_align(jl_value_t *dt)
{
    if (jl_is_tuple(dt)) {
        size_t i, l = jl_tuple_len(dt), align = 0;
        for (i = 0; i < l; i++) {
            size_t l = jl_new_bits_align(jl_tupleref(dt,i));
            if (l > align)
                align = l;
        }
        return align;
    }
    return ((jl_datatype_t*)dt)->alignment;
}
Esempio n. 9
0
static void jl_serialize_methlist(ios_t *s, jl_methlist_t *ml)
{
    while (ml != NULL) {
        jl_serialize_value(s, ml->sig);
        assert(jl_is_tuple(ml->sig));
        write_int8(s, ml->va);
        jl_serialize_value(s, ml->tvars);
        jl_serialize_value(s, ml->func);
        jl_serialize_value(s, ml->invokes);
        ml = ml->next;
    }
    jl_serialize_value(s, NULL);
}
Esempio n. 10
0
// get array of var info records for captured vars
jl_array_t *jl_lam_capt(jl_expr_t *l)
{
    if (jl_is_tuple(l)) {
        // in compressed form
        return (jl_array_t*)jl_tupleref(l, 3);
    }
    assert(jl_is_expr(l));
    jl_value_t *le = jl_exprarg(l, 1);
    assert(jl_is_array(le));
    jl_value_t *ll = jl_cellref(le, 2);
    assert(jl_is_array(ll));
    return (jl_array_t*)ll;
}
Esempio n. 11
0
DLLEXPORT
jl_value_t *jl_new_closure_internal(jl_lambda_info_t *li, jl_value_t *env)
{
    assert(jl_is_lambda_info(li));
    assert(jl_is_tuple(env));
    jl_function_t *f=NULL;
    // note: env is pushed here to make codegen a little easier
    JL_GC_PUSH(&f, &env);
    f = jl_new_closure(li->fptr ? li->fptr : jl_trampoline, env);
    f->linfo = li;
    JL_GC_POP();
    return (jl_value_t*)f;
}
Esempio n. 12
0
int jl_egal(jl_value_t *a, jl_value_t *b)
{
    if (a == b)
        return 1;
    jl_value_t *ta = (jl_value_t*)jl_typeof(a);
    if (ta != (jl_value_t*)jl_typeof(b))
        return 0;
    if (jl_is_tuple(a)) {
        size_t l = jl_tuple_len(a);
        if (l != jl_tuple_len(b))
            return 0;
        for(size_t i=0; i < l; i++) {
            if (!jl_egal(jl_tupleref(a,i),jl_tupleref(b,i)))
                return 0;
        }
        return 1;
    }
    jl_datatype_t *dt = (jl_datatype_t*)ta;
    if (dt == jl_datatype_type) {
        jl_datatype_t *dta = (jl_datatype_t*)a;
        jl_datatype_t *dtb = (jl_datatype_t*)b;
        return dta->name == dtb->name &&
            jl_egal((jl_value_t*)dta->parameters, (jl_value_t*)dtb->parameters);
    }
    if (dt->mutabl) return 0;
    size_t sz = dt->size;
    if (sz == 0) return 1;
    size_t nf = jl_tuple_len(dt->names);
    if (nf == 0) {
        return bits_equal(jl_data_ptr(a), jl_data_ptr(b), sz);
    }
    for (size_t f=0; f < nf; f++) {
        size_t offs = dt->fields[f].offset;
        char *ao = (char*)jl_data_ptr(a) + offs;
        char *bo = (char*)jl_data_ptr(b) + offs;
        int eq;
        if (dt->fields[f].isptr) {
            jl_value_t *af = *(jl_value_t**)ao;
            jl_value_t *bf = *(jl_value_t**)bo;
            if (af == bf) eq = 1;
            else if (af==NULL || bf==NULL) eq = 0;
            else eq = jl_egal(af, bf);
        }
        else {
            eq = bits_equal(ao, bo, dt->fields[f].size);
        }
        if (!eq) return 0;
    }
    return 1;
}
Esempio n. 13
0
File: gc.c Progetto: Carreau/julia
static void run_finalizer(jl_value_t *o, jl_value_t *ff)
{
    jl_function_t *f;
    while (1) {
        if (jl_is_tuple(ff))
            f = (jl_function_t*)jl_t0(ff);
        else
            f = (jl_function_t*)ff;
        assert(jl_is_function(f));
        JL_TRY {
            jl_apply(f, (jl_value_t**)&o, 1);
        }
        JL_CATCH {
            JL_PRINTF(JL_STDERR, "error in running finalizer: ");
            jl_static_show(JL_STDERR, jl_exception_in_transit);
            JL_PUTC('\n',JL_STDERR);
        }
        if (jl_is_tuple(ff))
            ff = jl_t1(ff);
        else
            break;
    }
}
Esempio n. 14
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);
    }
}
Esempio n. 15
0
static int is_ast_node(jl_value_t *v)
{
    if (jl_is_lambda_info(v)) {
        jl_lambda_info_t *li = (jl_lambda_info_t*)v;
        if (jl_is_expr(li->ast))
            li->ast = jl_compress_ast(li, li->ast);
        return 0;
    }
    return jl_is_symbol(v) || jl_is_expr(v) ||
        jl_typeis(v, jl_array_any_type) || jl_is_tuple(v) ||
        jl_is_union_type(v) || jl_is_int32(v) || jl_is_int64(v) ||
        jl_is_symbolnode(v) || jl_is_bool(v) || jl_is_typevar(v) ||
        jl_is_topnode(v) || jl_is_quotenode(v) || jl_is_gotonode(v) ||
        jl_is_labelnode(v) || jl_is_linenode(v) || jl_is_getfieldnode(v);
}
Esempio n. 16
0
SEXP jr_cast(jl_value_t *tt){
    SEXP ans = R_NilValue;
    JL_GC_PUSH1(&tt);
    if (jl_is_nothing(tt) || jl_is_null(tt))
        return ans;

    if (jl_is_array(tt))
    {
        ans = jr_array(tt);
    }
    else if(jl_isa(tt, "Range"))
    {
        ans = jr_range(tt);
    }
    else if(jl_isa(tt, "DataArray"))
    {
        ans = jr_data_array(tt);
    }
    else if(jl_isa(tt, "DataFrame"))
    {
        ans = jr_data_frame(tt);
    }
    else if (jl_is_tuple(tt))
    {
        PROTECT(ans = Rf_allocVector(VECSXP, jl_tuple_len(tt)));
        for (int i = 0; i < jl_tuple_len(tt); i++)
            SET_VECTOR_ELT(ans, i, jr_cast(jl_tupleref(tt, i)));
        UNPROTECT(1);
    }
    else if(jl_isa(tt, "Dict"))
    {
        ans = jr_dict(tt);
    }
    else if(jl_is_function(tt))
    {
        ans = jr_func(tt);
    }
    else
    {
        ans = jr_scalar(tt);
    }
    JL_GC_POP();
    if (ans == R_NilValue)
    {
        jl_error("invaild object");
    }
    return ans;
}
Esempio n. 17
0
File: gf.c Progetto: cshen/julia
static void print_sig(jl_tuple_t *type)
{
    size_t i;
    for(i=0; i < type->length; i++) {
        if (i > 0) ios_printf(ios_stderr, ", ");
        jl_value_t *v = jl_tupleref(type,i);
        if (jl_is_tuple(v)) {
            ios_putc('(', ios_stderr);
            print_sig((jl_tuple_t*)v);
            ios_putc(')', ios_stderr);
        }
        else {
            ios_printf(ios_stderr, "%s", type_summary(v));
        }
    }
}
Esempio n. 18
0
void jl_show(jl_value_t *stream, jl_value_t *v)
{
    if (jl_base_module) {
        if (jl_show_gf == NULL) {
            jl_show_gf = (jl_function_t*)jl_get_global(jl_base_module, jl_symbol("show"));
        }
        if (jl_show_gf==NULL || stream==NULL) {
            JL_PRINTF(JL_STDERR, " could not show value of type %s",
                      jl_is_tuple(v) ? "Tuple" : 
                      ((jl_datatype_t*)jl_typeof(v))->name->name->name);
            return;
        }
        jl_value_t *args[2] = {stream,v};
        jl_apply(jl_show_gf, args, 2);
    }
}
Esempio n. 19
0
File: ast.c Progetto: rpruim/julia
// given a new lambda_info with static parameter values, make a copy
// of the tree with declared types evaluated and static parameters passed
// on to all enclosed functions.
// this tree can then be further mutated by optimization passes.
DLLEXPORT
jl_value_t *jl_prepare_ast(jl_lambda_info_t *li, jl_tuple_t *sparams)
{
    jl_tuple_t *spenv = NULL;
    jl_value_t *l_ast = li->ast;
    if (l_ast == NULL) return NULL;
    jl_value_t *ast = l_ast;
    JL_GC_PUSH(&spenv, &ast);
    if (jl_is_tuple(ast))
        ast = jl_uncompress_ast((jl_tuple_t*)ast);
    spenv = jl_tuple_tvars_to_symbols(sparams);
    ast = copy_ast(ast, sparams);
    eval_decl_types(jl_lam_vinfo((jl_expr_t*)ast), spenv);
    eval_decl_types(jl_lam_capt((jl_expr_t*)ast), spenv);
    JL_GC_POP();
    return ast;
}
Esempio n. 20
0
static int type_contains(jl_value_t *ty, jl_value_t *x)
{
    if (ty == x) return 1;
    if (jl_is_tuple(ty)) {
        size_t i, l=jl_tuple_len(ty);
        for(i=0; i < l; i++) {
            jl_value_t *e = jl_tupleref(ty,i);
            if (e==x || type_contains(e, x))
                return 1;
        }
    }
    if (jl_is_uniontype(ty))
        return type_contains(jl_fieldref(ty,0), x);
    if (jl_is_datatype(ty))
        return type_contains((jl_value_t*)((jl_datatype_t*)ty)->parameters, x);
    return 0;
}
Esempio n. 21
0
DLLEXPORT void jl_show_any(jl_value_t *str, jl_value_t *v)
{
    uv_stream_t *s = ((uv_stream_t**)str)[1];
    // 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_data_ptr(v));
    }
    else {
        jl_value_t *t = (jl_value_t*)jl_typeof(v);
        assert(jl_is_datatype(t));
        jl_datatype_t *dt = (jl_datatype_t*)t;
        show_type(str, t);
        JL_PUTC('(', s);
        if (jl_tuple_len(dt->names)>0 || dt->size==0) {
            size_t i;
            size_t n = jl_tuple_len(dt->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_datatype_size(dt);
            char *data = (char*)jl_data_ptr(v);
            JL_PUTS("0x", s);
            for(int i=nb-1; i >= 0; --i)
                jl_printf(s, "%02hhx", data[i]);
        }
        JL_PUTC(')', s);
    }
}
Esempio n. 22
0
File: jl_uv.c Progetto: jskDr/julia
DLLEXPORT void jl_uv_alloc_buf(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
{
    if (handle->data) {
        jl_value_t *ret = JULIA_CB(alloc_buf,handle->data,1,CB_UINT,suggested_size);
        assert(jl_is_tuple(ret) && jl_is_pointer(jl_t0(ret)));
        buf->base = (char*)jl_unbox_voidpointer(jl_t0(ret));
#ifdef _P64
        assert(jl_is_uint64(jl_t1(ret)));
        buf->len = jl_unbox_uint64(jl_t1(ret));
#else
        assert(jl_is_uint32(jl_t1(ret)));
        buf->len = jl_unbox_uint32(jl_t1(ret));
#endif
    }
    else {
        buf->len = 0;
    }
}
Esempio n. 23
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;
}
Esempio n. 24
0
static jl_value_t *jl_new_bits_internal(jl_value_t *dt, void *data, size_t *len)
{
    if (jl_is_tuple(dt)) {
        jl_tuple_t *tuple = (jl_tuple_t*)dt;
        *len = LLT_ALIGN(*len, jl_new_bits_align(dt));
        size_t i, l = jl_tuple_len(tuple);
        jl_value_t *v = (jl_value_t*) jl_alloc_tuple(l);
        JL_GC_PUSH1(v);
        for (i = 0; i < l; i++) {
            jl_tupleset(v,i,jl_new_bits_internal(jl_tupleref(tuple,i), (char*)data, len));
        }
        JL_GC_POP();
        return v;
    }

    jl_datatype_t *bt = (jl_datatype_t*)dt;
    size_t nb = jl_datatype_size(bt);
    if (nb == 0)
        return jl_new_struct_uninit(bt);
    *len = LLT_ALIGN(*len, bt->alignment);
    data = (char*)data + (*len);
    *len += nb;
    if (bt == jl_uint8_type)   return jl_box_uint8(*(uint8_t*)data);
    if (bt == jl_int64_type)   return jl_box_int64(*(int64_t*)data);
    if (bt == jl_bool_type)    return (*(int8_t*)data) ? jl_true:jl_false;
    if (bt == jl_int32_type)   return jl_box_int32(*(int32_t*)data);
    if (bt == jl_float64_type) return jl_box_float64(*(double*)data);

    jl_value_t *v =
        (jl_value_t*)allocobj((NWORDS(LLT_ALIGN(nb,sizeof(void*)))+1)*
                              sizeof(void*));
    v->type = (jl_value_t*)bt;
    switch (nb) {
    case  1: *(int8_t*)   jl_data_ptr(v) = *(int8_t*)data;    break;
    case  2: *(int16_t*)  jl_data_ptr(v) = *(int16_t*)data;   break;
    case  4: *(int32_t*)  jl_data_ptr(v) = *(int32_t*)data;   break;
    case  8: *(int64_t*)  jl_data_ptr(v) = *(int64_t*)data;   break;
    case 16: *(bits128_t*)jl_data_ptr(v) = *(bits128_t*)data; break;
    default: memcpy(jl_data_ptr(v), data, nb);
    }
    return v;
}
Esempio n. 25
0
DLLEXPORT
jl_value_t *jl_new_closure_internal(jl_lambda_info_t *li, jl_value_t *env)
{
    assert(jl_is_lambda_info(li));
    assert(jl_is_tuple(env));
    jl_function_t *f=NULL;
    // note: env is pushed here to make codegen a little easier
    JL_GC_PUSH(&f, &env);
    if (li->fptr != NULL) {
        // function has been compiled
        f = jl_new_closure(li->fptr, env);
    }
    else {
        f = jl_new_closure(jl_trampoline, NULL);
        f->env = (jl_value_t*)jl_tuple2((jl_value_t*)f, env);
    }
    f->linfo = li;
    JL_GC_POP();
    return (jl_value_t*)f;
}
Esempio n. 26
0
//Convert Julia Type To R,Real interface
SEXP Julia_R(jl_value_t *Var)
{
  SEXP ans = R_NilValue;
  if (jl_is_nothing(Var) || jl_is_null(Var))
    return ans;

  //Array To Vector
  JL_GC_PUSH1(&Var);
  if (jl_is_array(Var))
  {
    ans = Julia_R_MD(Var);
  }
  else if (jl_is_DataArrayFrame(Var))
  {
    //try to load DataArrays DataFrames package
    if (!LoadDF())
    {
      JL_GC_POP();
      return R_NilValue;
    }
    if (jl_is_NAtype(Var))
      ans = Julia_R_Scalar_NA(Var);
    else if (jl_is_DataFrame(Var))
      ans = Julia_R_MD_NA_DataFrame(Var);
    else if (jl_is_DataArray(Var))
      ans = Julia_R_MD_NA(Var);
    else if (jl_is_PooledDataArray(Var))
      ans = Julia_R_MD_NA_Factor(Var);    
  }
  else if (jl_is_tuple(Var))
  {
      PROTECT(ans = allocVector(VECSXP, jl_tuple_len(Var)));
      for (int i = 0; i < jl_tuple_len(Var); i++)
        SET_ELEMENT(ans, i, Julia_R(jl_tupleref(Var, i)));
      UNPROTECT(1);
  }
  else
    ans = Julia_R_Scalar(Var);
  JL_GC_POP();
  return ans;
}
Esempio n. 27
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. 28
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_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))
            jl_error("in method definition: not a generic function");
    }
    JL_GC_PUSH(&gf);
    assert(jl_is_function(f));
    assert(jl_is_tuple(argtypes));
    check_type_tuple(argtypes, name, "method definition");
    jl_add_method((jl_function_t*)gf, argtypes, f);
    JL_GC_POP();
    return gf;
}
Esempio n. 29
0
int jl_egal(jl_value_t *a, jl_value_t *b)
{
    if (a == b)
        return 1;
    jl_value_t *ta = (jl_value_t*)jl_typeof(a);
    if (ta != (jl_value_t*)jl_typeof(b))
        return 0;
    if (jl_is_bits_type(ta)) {
        size_t nb = jl_bitstype_nbits(ta)/8;
        switch (nb) {
        case 1:
            return *(int8_t*)jl_bits_data(a) == *(int8_t*)jl_bits_data(b);
        case 2:
            return *(int16_t*)jl_bits_data(a) == *(int16_t*)jl_bits_data(b);
        case 4:
            return *(int32_t*)jl_bits_data(a) == *(int32_t*)jl_bits_data(b);
        case 8:
            return *(int64_t*)jl_bits_data(a) == *(int64_t*)jl_bits_data(b);
        default:
            return memcmp(jl_bits_data(a), jl_bits_data(b), nb)==0;
        }
    }
    if (jl_is_tuple(a)) {
        size_t l = jl_tuple_len(a);
        if (l != jl_tuple_len(b))
            return 0;
        for(size_t i=0; i < l; i++) {
            if (!jl_egal(jl_tupleref(a,i),jl_tupleref(b,i)))
                return 0;
        }
        return 1;
    }
    if (ta == (jl_value_t*)jl_union_kind)
        return jl_egal(jl_fieldref(a,0), jl_fieldref(b,0));
    return 0;
}
Esempio n. 30
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_typecheck(arg1, (jl_value_t*)jl_voidpointer_type,
                           "ccall: function argument not a pointer or valid constant", 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__
            fptr = jl_dlsym_e(jl_dl_handle, f_name);
            if (!fptr) {
                //TODO: when one of these succeeds, store the f_lib name (and clear fptr)
                fptr = jl_dlsym_e(jl_kernel32_handle, f_name);
                if (!fptr) {
                    fptr = jl_dlsym_e(jl_ntdll_handle, f_name);
                    if (!fptr) {
                        fptr = jl_dlsym_e(jl_crtdll_handle, f_name);
                        if (!fptr) {
                            fptr = jl_dlsym(jl_winsock_handle, f_name);
                        }
                    }
                }
            }
            else {
                // available in process symbol table
                fptr = NULL;
            }
#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_type_to_llvm(rt);
    if (lrt == NULL) {
        JL_GC_POP();
        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_seq_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_type_to_llvm(tti);
        if (t == NULL) {
            JL_GC_POP();
            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) {
        Value *ary = emit_expr(args[4], ctx);
        JL_GC_POP();
        return mark_julia_type(builder.CreateBitCast(emit_arrayptr(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) {
            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);
    return mark_julia_type(result, rt);
}