Ejemplo n.º 1
0
static Type *julia_type_to_llvm(jl_value_t *jt, jl_codectx_t *ctx)
{
    if (jt == (jl_value_t*)jl_bool_type) return T_int1;
    if (jt == (jl_value_t*)jl_float32_type) return T_float32;
    if (jt == (jl_value_t*)jl_float64_type) return T_float64;
    //if (jt == (jl_value_t*)jl_null) return T_void;
    if (jl_is_bits_type(jt) && jl_is_cpointer_type(jt)) {
        Type *lt = julia_type_to_llvm(jl_tparam0(jt), ctx);
        if (lt == NULL)
            return NULL;
        if (lt == T_void)
            lt = T_int8;
        return PointerType::get(lt, 0);
    }
    if (jl_is_bits_type(jt)) {
        int nb = jl_bitstype_nbits(jt);
        if (nb == 8)  return T_int8;
        if (nb == 16) return T_int16;
        if (nb == 32) return T_int32;
        if (nb == 64) return T_int64;
        else          return Type::getIntNTy(getGlobalContext(), nb);
    }
    if (jt == (jl_value_t*)jl_bottom_type) return T_void;
    //if (jt == (jl_value_t*)jl_any_type)
    //    return jl_pvalue_llvmt;
    return jl_pvalue_llvmt;
    //emit_type_error(literal_pointer_val(jt), (jl_value_t*)jl_bits_kind,
    //                "conversion to native type", ctx);
    //return NULL;
}
Ejemplo n.º 2
0
jl_value_t *jl_arrayref(jl_array_t *a, size_t i)
{
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(jl_typeof(a));
    jl_value_t *elt;
    if (jl_is_bits_type(el_type)) {
        if (el_type == (jl_type_t*)jl_bool_type) {
            if (((int8_t*)a->data)[i] != 0)
                return jl_true;
            return jl_false;
        }
        elt = new_scalar((jl_bits_type_t*)el_type);
        size_t nb = a->elsize;
        switch (nb) {
        case 1:
            *(int8_t*)jl_bits_data(elt)  = ((int8_t*)a->data)[i];  break;
        case 2:
            *(int16_t*)jl_bits_data(elt) = ((int16_t*)a->data)[i]; break;
        case 4:
            *(int32_t*)jl_bits_data(elt) = ((int32_t*)a->data)[i]; break;
        case 8:
            *(int64_t*)jl_bits_data(elt) = ((int64_t*)a->data)[i]; break;
        case 16:
            *(bits128_t*)jl_bits_data(elt) = ((bits128_t*)a->data)[i]; break;
        default:
            memcpy(jl_bits_data(elt), &((char*)a->data)[i*nb], nb);
        }
    }
    else {
        elt = ((jl_value_t**)a->data)[i];
        if (elt == NULL) {
            jl_undef_ref_error();
        }
    }
    return elt;
}
Ejemplo n.º 3
0
void jl_arrayset(jl_array_t *a, size_t i, jl_value_t *rhs)
{
    jl_value_t *el_type = jl_tparam0(jl_typeof(a));
    if (el_type != (jl_value_t*)jl_any_type) {
        if (!jl_subtype(rhs, el_type, 1))
            jl_type_error("arrayset", el_type, rhs);
    }
    if (jl_is_bits_type(el_type)) {
        size_t nb = a->elsize;
        switch (nb) {
        case 1:
            ((int8_t*)a->data)[i]  = *(int8_t*)jl_bits_data(rhs);  break;
        case 2:
            ((int16_t*)a->data)[i] = *(int16_t*)jl_bits_data(rhs); break;
        case 4:
            ((int32_t*)a->data)[i] = *(int32_t*)jl_bits_data(rhs); break;
        case 8:
            ((int64_t*)a->data)[i] = *(int64_t*)jl_bits_data(rhs); break;
        case 16:
            ((bits128_t*)a->data)[i] = *(bits128_t*)jl_bits_data(rhs); break;
        default:
            memcpy(&((char*)a->data)[i*nb], jl_bits_data(rhs), nb);
        }
    }
    else {
        ((jl_value_t**)a->data)[i] = rhs;
    }
}
Ejemplo n.º 4
0
void jl_compute_struct_offsets(jl_struct_type_t *st)
{
    size_t sz = 0, alignm = 0;

    for(size_t i=0; i < st->types->length; i++) {
        jl_value_t *ty = jl_tupleref(st->types, i);
        size_t fsz, al;
        if (jl_is_bits_type(ty)) {
            fsz = jl_bitstype_nbits(ty)/8;
            al = fsz;   // alignment == size for bits types
            st->fields[i].isptr = 0;
        }
        else {
            fsz = sizeof(void*);
            al = fsz;
            st->fields[i].isptr = 1;
        }
        sz = LLT_ALIGN(sz, al);
        if (al > alignm)
            alignm = al;
        st->fields[i].offset = sz;
        st->fields[i].size = fsz;
        sz += fsz;
    }
    st->alignment = alignm;
    st->size = LLT_ALIGN(sz, alignm);
}
Ejemplo n.º 5
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;
    }
    return 0;
}
Ejemplo n.º 6
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) && addressOf) {
        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);
        }
        Value *p = builder.CreateCall3(value_to_pointer_func,
                                       literal_pointer_val(jl_tparam0(jt)), jv,
                                       ConstantInt::get(T_int32, argn));
        assert(ty->isPointerTy());
        return builder.CreateBitCast(p, ty);
    }
    // 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);
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
// this is used to wrap values for generic contexts, where a
// dynamically-typed value is required (e.g. argument to unknown function).
// if it's already a pointer it's left alone.
static Value *boxed(Value *v)
{
    Type *t = v->getType();
    if (t == jl_pvalue_llvmt)
        return v;
    if (t == T_void)
        return literal_pointer_val((jl_value_t*)jl_nothing);
    if (t == T_int1) return julia_bool(v);
    jl_value_t *jt = julia_type_of(v);
    jl_bits_type_t *jb = (jl_bits_type_t*)jt;
    if (jb == jl_int8_type)
        return builder.CreateCall(box_int8_func,
                                  builder.CreateSExt(v, T_int32));
    if (jb == jl_int16_type) return builder.CreateCall(box_int16_func, v);
    if (jb == jl_int32_type) return builder.CreateCall(box_int32_func, v);
    if (jb == jl_int64_type) return builder.CreateCall(box_int64_func, v);
    if (jb == jl_float32_type) return builder.CreateCall(box_float32_func, v);
    //if (jb == jl_float64_type) return builder.CreateCall(box_float64_func, v);
    if (jb == jl_float64_type) {
        // manually inline alloc & init of Float64 box. cheap, I know.
#ifdef __LP64__
        Value *newv = builder.CreateCall(jlalloc2w_func);
#else
        Value *newv = builder.CreateCall(jlalloc3w_func);
#endif
        return init_bits_value(newv, jt, t, v);
    }
    if (jb == jl_uint8_type)
        return builder.CreateCall(box_uint8_func,
                                  builder.CreateZExt(v, T_int32));
    if (jb == jl_uint16_type) return builder.CreateCall(box_uint16_func, v);
    if (jb == jl_uint32_type) return builder.CreateCall(box_uint32_func, v);
    if (jb == jl_uint64_type) return builder.CreateCall(box_uint64_func, v);
    if (jb == jl_char_type)   return builder.CreateCall(box_char_func, v);
    // TODO: skip the call for constant arguments
    if (jl_is_bits_type(jt)) {
        if (v->getType()->isPointerTy()) {
            v = builder.CreatePtrToInt(v, T_size);
        }
        int nb = jl_bitstype_nbits(jt);
        if (nb == 8)
            return builder.CreateCall2(box8_func,  literal_pointer_val(jt), v);
        if (nb == 16)
            return builder.CreateCall2(box16_func, literal_pointer_val(jt), v);
        if (nb == 32)
            return builder.CreateCall2(box32_func, literal_pointer_val(jt), v);
        if (nb == 64)
            return builder.CreateCall2(box64_func, literal_pointer_val(jt), v);
        size_t sz = sizeof(void*) + (nb+7)/8;
        Value *newv = builder.CreateCall(jlallocobj_func,
                                         ConstantInt::get(T_size, sz));
        // TODO: make sure this is rooted. I think it is.
        return init_bits_value(newv, jt, t, v);
    }
    assert("Don't know how to box this type" && false);
    return NULL;
}
Ejemplo n.º 9
0
Archivo: gf.c Proyecto: 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;
}
Ejemplo n.º 10
0
jl_array_t *jl_ptr_to_array(jl_type_t *atype, void *data, jl_tuple_t *dims,
                            int julia_mallocated)
{
    size_t i, elsz, nel=1;
    jl_array_t *a;
    size_t ndims = jl_tuple_len(dims);

    for(i=0; i < ndims; i++) {
        nel *= jl_unbox_long(jl_tupleref(dims, i));
    }
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype);

    int isunboxed = jl_is_bits_type(el_type);
    if (isunboxed)
        elsz = jl_bitstype_nbits(el_type)/8;
    else
        elsz = sizeof(void*);

    int ndimwords = (ndims > 2 ? (ndims-2) : 0);
#ifndef __LP64__
    // on 32-bit, ndimwords must be odd to preserve 8-byte alignment
    ndimwords += (~ndimwords)&1;
#endif
    a = allocobj(sizeof(jl_array_t) + ndimwords*sizeof(size_t));
    a->type = atype;
    a->data = data;
    a->length = nel;
    a->elsize = elsz;
    a->ptrarray = !isunboxed;
    a->ndims = ndims;

    if (julia_mallocated) {
        a->reshaped = 0;
        jl_gc_acquire_buffer(data);
    }
    else {
        // this marks the array as not owning its buffer
        a->reshaped = 1;
        *((jl_array_t**)(&a->_space[0] + ndimwords*sizeof(size_t))) = a;
    }

    if (ndims == 1) {
        a->nrows = a->length;
        a->maxsize = a->length;
        a->offset = 0;
    }
    else {
        size_t *adims = &a->nrows;
        for(i=0; i < ndims; i++) {
            adims[i] = jl_unbox_long(jl_tupleref(dims, i));
        }
    }
    
    return a;
}
Ejemplo n.º 11
0
Archivo: gf.c Proyecto: 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;
}
Ejemplo n.º 12
0
static void *array_new_buffer(jl_array_t *a, size_t newlen)
{
    size_t nbytes = newlen * a->elsize;
    if (a->elsize == 1) {
        nbytes++;
    }
    int isunboxed = jl_is_bits_type(jl_tparam0(jl_typeof(a)));
    char *newdata = alloc_array_buffer(nbytes, isunboxed);
    if (a->elsize == 1) newdata[nbytes-1] = '\0';
    return newdata;
}
Ejemplo n.º 13
0
// this is used to wrap values for generic contexts, where a
// dynamically-typed value is required (e.g. argument to unknown function).
// if it's already a pointer it's left alone.
static Value *boxed(Value *v)
{
    Type *t = v->getType();
    if (t == jl_pvalue_llvmt)
        return v;
    if (t == T_void)
        return literal_pointer_val((jl_value_t*)jl_nothing);
    if (t == T_int1) return julia_bool(v);
    jl_value_t *jt = julia_type_of(v);
    jl_bits_type_t *jb = (jl_bits_type_t*)jt;
    if (jb == jl_int8_type)
        return builder.CreateCall(box_int8_func,
                                  builder.CreateSExt(v, T_int32));
    if (jb == jl_int16_type) return builder.CreateCall(box_int16_func, v);
    if (jb == jl_int32_type) return builder.CreateCall(box_int32_func, v);
    if (jb == jl_int64_type) return builder.CreateCall(box_int64_func, v);
    if (jb == jl_float32_type) return builder.CreateCall(box_float32_func, v);
    if (jb == jl_float64_type) return builder.CreateCall(box_float64_func, v);
    if (jb == jl_uint8_type)
        return builder.CreateCall(box_uint8_func,
                                  builder.CreateZExt(v, T_int32));
    if (jb == jl_uint16_type) return builder.CreateCall(box_uint16_func, v);
    if (jb == jl_uint32_type) return builder.CreateCall(box_uint32_func, v);
    if (jb == jl_uint64_type) return builder.CreateCall(box_uint64_func, v);
    if (jb == jl_char_type)   return builder.CreateCall(box_char_func, v);
    // TODO: skip the call for constant arguments
    if (jl_is_bits_type(jt)) {
        if (v->getType()->isPointerTy()) {
            v = builder.CreatePtrToInt(v, T_size);
        }
        int nb = jl_bitstype_nbits(jt);
        if (nb == 8)
            return builder.CreateCall2(box8_func,  literal_pointer_val(jt), v);
        if (nb == 16)
            return builder.CreateCall2(box16_func, literal_pointer_val(jt), v);
        if (nb == 32)
            return builder.CreateCall2(box32_func, literal_pointer_val(jt), v);
        if (nb == 64)
            return builder.CreateCall2(box64_func, literal_pointer_val(jt), v);
        size_t sz = sizeof(void*) + (nb+7)/8;
        Value *newv = builder.CreateCall(jlallocobj_func,
                                         ConstantInt::get(T_size, sz));
        builder.CreateStore(literal_pointer_val(jt),
                            builder.CreateBitCast(newv, jl_ppvalue_llvmt));
        builder.CreateStore(v,
                            builder.CreateBitCast(bitstype_pointer(newv),
                                                  PointerType::get(t,0)));
        // TODO: make sure this is rooted. I think it is.
        return builder.CreateBitCast(newv, jl_pvalue_llvmt);
    }
    assert("Don't know how to box this type" && false);
    return NULL;
}
Ejemplo n.º 14
0
static Value *typed_store(Value *ptr, Value *idx_0based, Value *rhs,
                          jl_value_t *jltype, jl_codectx_t *ctx)
{
    Type *elty = julia_type_to_llvm(jltype);
    assert(elty != NULL);
    if (elty==T_int1) { elty = T_int8; }
    if (jl_is_bits_type(jltype))
        rhs = emit_unbox(elty, PointerType::get(elty,0), rhs);
    else
        rhs = boxed(rhs);
    Value *data = builder.CreateBitCast(ptr, PointerType::get(elty, 0));
    return builder.CreateStore(rhs, builder.CreateGEP(data, idx_0based));
}
Ejemplo n.º 15
0
void jl_arrayset(jl_array_t *a, size_t i, jl_value_t *rhs)
{
    jl_value_t *el_type = jl_tparam0(jl_typeof(a));
    if (el_type != (jl_value_t*)jl_any_type) {
        if (!jl_subtype(rhs, el_type, 1))
            jl_type_error("arrayset", el_type, rhs);
    }
    if (jl_is_bits_type(el_type)) {
        jl_assign_bits(&((char*)a->data)[i*a->elsize], rhs);
    }
    else {
        ((jl_value_t**)a->data)[i] = rhs;
    }
}
Ejemplo n.º 16
0
jl_array_t *jl_ptr_to_array(jl_type_t *atype, void *data, jl_tuple_t *dims,
                            int own_buffer)
{
    size_t i, elsz, nel=1;
    jl_array_t *a;
    size_t ndims = jl_tuple_len(dims);

    for(i=0; i < ndims; i++) {
        nel *= jl_unbox_long(jl_tupleref(dims, i));
    }
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype);

    int isunboxed = jl_is_bits_type(el_type);
    if (isunboxed)
        elsz = jl_bitstype_nbits(el_type)/8;
    else
        elsz = sizeof(void*);

    int ndimwords = jl_array_ndimwords(ndims);
    a = allocobj((sizeof(jl_array_t) + ndimwords*sizeof(size_t)+15)&-16);
    a->type = atype;
    a->data = data;
    a->length = nel;
    a->elsize = elsz;
    a->ptrarray = !isunboxed;
    a->ndims = ndims;

    if (own_buffer) {
        a->ismalloc = 1;
        jl_array_data_owner(a) = (jl_value_t*)jl_gc_acquire_buffer(data,nel*elsz);
    }
    else {
        a->ismalloc = 0;
        jl_array_data_owner(a) = (jl_value_t*)a;
    }

    if (ndims == 1) {
        a->nrows = a->length;
        a->maxsize = a->length;
        a->offset = 0;
    }
    else {
        size_t *adims = &a->nrows;
        for(i=0; i < ndims; i++) {
            adims[i] = jl_unbox_long(jl_tupleref(dims, i));
        }
    }
    
    return a;
}
Ejemplo n.º 17
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);
    }
}
Ejemplo n.º 18
0
jl_value_t *jl_arrayref(jl_array_t *a, size_t i)
{
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(jl_typeof(a));
    jl_value_t *elt;
    if (jl_is_bits_type(el_type)) {
        elt = jl_new_bits((jl_bits_type_t*)el_type,
                          &((char*)a->data)[i*a->elsize]);
    }
    else {
        elt = ((jl_value_t**)a->data)[i];
        if (elt == NULL) {
            jl_raise(jl_undefref_exception);
        }
    }
    return elt;
}
Ejemplo n.º 19
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);
    }
}
Ejemplo n.º 20
0
// this is used to wrap values for generic contexts, where a
// dynamically-typed value is required (e.g. argument to unknown function).
// if it's already a pointer it's left alone.
static Value *boxed(Value *v, jl_value_t *jt)
{
    Type *t = v->getType();
    if (t == jl_pvalue_llvmt)
        return v;
    if (t == T_void)
        return literal_pointer_val((jl_value_t*)jl_nothing);
    if (t == T_int1) return julia_bool(v);
    if (jt == NULL)
        jt = julia_type_of(v);
    jl_bits_type_t *jb = (jl_bits_type_t*)jt;
    if (jb == jl_int8_type)
        return builder.CreateCall(box_int8_func,
                                  builder.CreateSExt(v, T_int32));
    if (jb == jl_int16_type) return builder.CreateCall(box_int16_func, v);
    if (jb == jl_int32_type) return builder.CreateCall(box_int32_func, v);
    if (jb == jl_int64_type) return builder.CreateCall(box_int64_func, v);
    if (jb == jl_float32_type) return builder.CreateCall(box_float32_func, v);
    //if (jb == jl_float64_type) return builder.CreateCall(box_float64_func, v);
    if (jb == jl_float64_type) {
        // manually inline alloc & init of Float64 box. cheap, I know.
#ifdef __LP64__
        Value *newv = builder.CreateCall(jlalloc2w_func);
#else
        Value *newv = builder.CreateCall(jlalloc3w_func);
#endif
        return init_bits_value(newv, literal_pointer_val(jt), t, v);
    }
    if (jb == jl_uint8_type)
        return builder.CreateCall(box_uint8_func,
                                  builder.CreateZExt(v, T_int32));
    if (jb == jl_uint16_type) return builder.CreateCall(box_uint16_func, v);
    if (jb == jl_uint32_type) return builder.CreateCall(box_uint32_func, v);
    if (jb == jl_uint64_type) return builder.CreateCall(box_uint64_func, v);
    if (jb == jl_char_type)   return builder.CreateCall(box_char_func, v);
    // TODO: skip the call for constant arguments
    if (!jl_is_bits_type(jt)) {
        assert("Don't know how to box this type" && false);
        return NULL;
    }
    int nb = jl_bitstype_nbits(jt);
    return allocate_box_dynamic(literal_pointer_val(jt), nb, v);
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
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);
    }
}
Ejemplo n.º 23
0
Archivo: gf.c Proyecto: 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;
}
Ejemplo n.º 24
0
// ** NOTE: julia_mallocated means buffer was allocated using julia_malloc.
// using the address of another array does not work!!
jl_array_t *jl_ptr_to_array_1d(jl_type_t *atype, void *data, size_t nel,
                               int julia_mallocated)
{
    size_t elsz;
    jl_array_t *a;
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype);

    int isunboxed = jl_is_bits_type(el_type);
    if (isunboxed)
        elsz = jl_bitstype_nbits(el_type)/8;
    else
        elsz = sizeof(void*);

    a = allocobj(sizeof(jl_array_t));
    a->type = atype;
    a->data = data;
    a->length = nel;
    a->elsize = elsz;
    a->ptrarray = !isunboxed;
    a->ndims = 1;

    if (julia_mallocated) {
        a->reshaped = 0;
        jl_gc_acquire_buffer(data);
    }
    else {
        // this marks the array as not owning its buffer
        a->reshaped = 1;
        *((jl_array_t**)(&a->_space[0])) = a;
    }

    a->nrows = a->length;
    a->maxsize = a->length;
    a->offset = 0;
    
    return a;
}
Ejemplo n.º 25
0
static Type *julia_type_to_llvm(jl_value_t *jt)
{
    if (jt == (jl_value_t*)jl_bool_type) return T_int1;
    if (jt == (jl_value_t*)jl_float32_type) return T_float32;
    if (jt == (jl_value_t*)jl_float64_type) return T_float64;
    if (jl_is_cpointer_type(jt)) {
        Type *lt = julia_type_to_llvm(jl_tparam0(jt));
        if (lt == NULL)
            return NULL;
        if (lt == T_void)
            lt = T_int8;
        return PointerType::get(lt, 0);
    }
    if (jl_is_bits_type(jt)) {
        int nb = jl_bitstype_nbits(jt);
        if (nb == 8)  return T_int8;
        if (nb == 16) return T_int16;
        if (nb == 32) return T_int32;
        if (nb == 64) return T_int64;
        else          return Type::getIntNTy(getGlobalContext(), nb);
    }
    if (jt == (jl_value_t*)jl_bottom_type) return T_void;
    return jl_pvalue_llvmt;
}
Ejemplo n.º 26
0
// own_buffer != 0 iff GC should call free() on this pointer eventually
jl_array_t *jl_ptr_to_array_1d(jl_type_t *atype, void *data, size_t nel,
                               int own_buffer)
{
    size_t elsz;
    jl_array_t *a;
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype);

    int isunboxed = jl_is_bits_type(el_type);
    if (isunboxed)
        elsz = jl_bitstype_nbits(el_type)/8;
    else
        elsz = sizeof(void*);

    a = allocobj((sizeof(jl_array_t)+jl_array_ndimwords(1)*sizeof(size_t)+15)&-16);
    a->type = atype;
    a->data = data;
    a->length = nel;
    a->elsize = elsz;
    a->ptrarray = !isunboxed;
    a->ndims = 1;

    if (own_buffer) {
        a->ismalloc = 1;
        jl_array_data_owner(a) = (jl_value_t*)jl_gc_acquire_buffer(data,nel*elsz);
    }
    else {
        a->ismalloc = 0;
        jl_array_data_owner(a) = (jl_value_t*)a;
    }

    a->nrows = a->length;
    a->maxsize = a->length;
    a->offset = 0;
    
    return a;
}
Ejemplo n.º 27
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);
}
Ejemplo n.º 28
0
jl_array_t *jl_reshape_array(jl_type_t *atype, jl_array_t *data,
                             jl_tuple_t *dims)
{
    size_t i;
    jl_array_t *a;
    size_t ndims = jl_tuple_len(dims);

    int ndimwords = jl_array_ndimwords(ndims);
    a = allocobj((sizeof(jl_array_t) + ndimwords*sizeof(size_t) + 15)&-16);
    a->type = atype;
    a->ndims = ndims;
    a->data = NULL;
    JL_GC_PUSH(&a);

    char *d = data->data;
    if (data->ndims == 1) d -= data->offset*data->elsize;
    if (d == jl_array_inline_data_area(data)) {
        if (data->ndims == 1) {
            // data might resize, so switch it to shared representation.
            // problem: we'd like to do that, but it might not be valid,
            // since the buffer might be used from C in a way that it's
            // assumed not to move. for now, just copy the data (note this
            // case only happens for sizes <= ARRAY_INLINE_NBYTES)
            jl_mallocptr_t *mp = array_new_buffer(data, data->length);
            memcpy(mp->ptr, data->data, data->length * data->elsize);
            a->data = mp->ptr;
            jl_array_data_owner(a) = (jl_value_t*)mp;
            a->ismalloc = 1;
            //data->data = mp->ptr;
            //data->offset = 0;
            //data->maxsize = data->length;
            //jl_array_data_owner(data) = (jl_value_t*)mp;
        }
        else {
            a->ismalloc = 0;
            jl_array_data_owner(a) = (jl_value_t*)data;
        }
    }
    else {
        a->ismalloc = data->ismalloc;
        jl_array_data_owner(a) = jl_array_data_owner(data);
    }

    if (a->data == NULL) a->data = data->data;
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype);
    if (jl_is_bits_type(el_type)) {
        a->elsize = jl_bitstype_nbits(el_type)/8;
        a->ptrarray = 0;
    }
    else {
        a->elsize = sizeof(void*);
        a->ptrarray = 1;
    }

    if (ndims == 1) {
        a->length = jl_unbox_long(jl_tupleref(dims,0));
        a->nrows = a->length;
        a->maxsize = a->length;
        a->offset = 0;
    }
    else {
        size_t *adims = &a->nrows;
        size_t l=1;
        for(i=0; i < ndims; i++) {
            adims[i] = jl_unbox_long(jl_tupleref(dims, i));
            l *= adims[i];
        }
        a->length = l;
    }
    JL_GC_POP();

    return a;
}
Ejemplo n.º 29
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);
}
Ejemplo n.º 30
0
static jl_array_t *_new_array(jl_type_t *atype,
                              uint32_t ndims, size_t *dims)
{
    size_t i, tot, nel=1;
    int isunboxed=0, elsz;
    void *data;
    jl_array_t *a;

    for(i=0; i < ndims; i++) {
        nel *= dims[i];
    }
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype);

    isunboxed = jl_is_bits_type(el_type);
    if (isunboxed) {
        elsz = jl_bitstype_nbits(el_type)/8;
        tot = elsz * nel;
        if (elsz == 1) {
            // hidden 0 terminator for all byte arrays
            tot++;
        }
    }
    else {
        elsz = sizeof(void*);
        tot = sizeof(void*) * nel;
    }

    int ndimwords = jl_array_ndimwords(ndims);
    if (tot <= ARRAY_INLINE_NBYTES) {
        size_t tsz = tot>sizeof(size_t) ? tot-sizeof(size_t) : tot;
        a = allocobj((sizeof(jl_array_t)+tsz+ndimwords*sizeof(size_t)+15)&-16);
        a->type = atype;
        a->ismalloc = 0;
        data = (&a->_space[0] + ndimwords*sizeof(size_t));
        if (tot > 0 && !isunboxed) {
            memset(data, 0, tot);
        }
    }
    else {
        a = allocobj((sizeof(jl_array_t)+ndimwords*sizeof(size_t)+15)&-16);
        JL_GC_PUSH(&a);
        a->type = atype;
        a->ismalloc = 1;
        // temporarily initialize to make gc-safe
        a->data = NULL;
        jl_value_t **powner = (jl_value_t**)(&a->_space[0] + ndimwords*sizeof(size_t));
        *powner = (jl_value_t*)jl_gc_managed_malloc(tot);
        data = ((jl_mallocptr_t*)*powner)->ptr;
        if (!isunboxed)
            memset(data, 0, tot);
        JL_GC_POP();
    }

    a->data = data;
    if (elsz == 1) ((char*)data)[tot-1] = '\0';
    a->length = nel;
    a->ndims = ndims;
    a->ptrarray = !isunboxed;
    a->elsize = elsz;
    if (ndims == 1) {
        a->nrows = nel;
        a->maxsize = nel;
        a->offset = 0;
    }
    else {
        size_t *adims = &a->nrows;
        for(i=0; i < ndims; i++)
            adims[i] = dims[i];
    }
    
    return a;
}