コード例 #1
0
ファイル: cgutils.cpp プロジェクト: ghaspias/julia
// 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;
}
コード例 #2
0
ファイル: cgutils.cpp プロジェクト: glycerine/julia
// 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;
}
コード例 #3
0
ファイル: cgutils.cpp プロジェクト: FizzyP/julia
// 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_datatype_t *jb = (jl_datatype_t*)jt;
    assert(jl_is_datatype(jb));
    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 _P64
        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_isbits(jt)) {
        assert("Don't know how to box this type" && false);
        return NULL;
    }
    if (!jb->abstract && jb->size == 0) {
        if (jb->instance == NULL)
            jl_new_struct_uninit(jb);
        assert(jb->instance != NULL);
        return literal_pointer_val(jb->instance);
    }
    return allocate_box_dynamic(literal_pointer_val(jt),jl_datatype_size(jt),v);
}