Esempio n. 1
0
unsigned get_type_alignment(type_t const *const type)
{
	switch (type->kind) {
	case TYPE_ERROR:
		return 0;
	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_COMPLEX:
	case TYPE_ENUM:
		return get_atomic_type_alignment(type->atomic.akind);
	case TYPE_COMPOUND_STRUCT:
	case TYPE_COMPOUND_UNION:
		return type->compound.compound->alignment;
	case TYPE_FUNCTION:
	case TYPE_VOID:
		return 1; /* GCC extension. */
	case TYPE_REFERENCE:
	case TYPE_POINTER:
		return pointer_properties.alignment;
	case TYPE_ARRAY:
		return get_type_alignment(type->array.element_type);
	case TYPE_TYPEDEF: {
		il_alignment_t const alignment = get_type_alignment(type->typedeft.typedefe->type);
		return MAX(alignment, type->typedeft.typedefe->alignment);
	}
	case TYPE_TYPEOF:
		return get_type_alignment(type->typeoft.typeof_type);
	case TYPE_BUILTIN_TEMPLATE:
		break;
	}
	panic("invalid type");
}
Esempio n. 2
0
/**
 * get alignment of a type when used inside a compound.
 * Some ABIs are broken and alignment inside a compound is different from
 * recommended alignment of a type
 */
static unsigned get_type_alignment_compound(type_t *const type)
{
	assert(!is_typeref(type));
	if (type->kind == TYPE_ATOMIC)
		return atomic_type_properties[type->atomic.akind].struct_alignment;
	return get_type_alignment(type);
}
Esempio n. 3
0
static ir_tarval *alignof_to_tarval(const typeprop_expression_t *expression)
{
	unsigned const alignment = expression->tp_expression
		? get_object_alignment(expression->tp_expression)
		: get_type_alignment(expression->type);
	ir_mode *const mode = get_ir_mode_storage(expression->base.type);
	return new_tarval_from_long(alignment, mode);
}
Esempio n. 4
0
static unsigned get_address_alignment(expression_t const *const expr)
{
	if (expr->kind == EXPR_UNARY_TAKE_ADDRESS) {
		return get_object_alignment(expr->unary.value);
	} else {
		type_t *const type = skip_typeref(expr->base.type);
		assert(is_type_pointer(type));
		return get_type_alignment(type->pointer.points_to);
	}
}
Esempio n. 5
0
static unsigned get_object_alignment(expression_t const *const expr)
{
	entity_t *ent;
	switch (expr->kind) {
	case EXPR_ARRAY_ACCESS:      return get_address_alignment(expr->array_access.array_ref);
	case EXPR_UNARY_DEREFERENCE: return get_address_alignment(expr->unary.value);
	case EXPR_REFERENCE:         ent = expr->reference.entity;      break;
	case EXPR_SELECT:            ent = expr->select.compound_entry; break;
	default:                     return get_type_alignment(expr->base.type);
	}
	assert(is_declaration(ent));
	return get_declaration_alignment(&ent->declaration);
}
Esempio n. 6
0
void gcji_create_array_type(void)
{
	ident *id = new_id_from_str("array");
	type_jarray = new_type_class(id);
	assert(type_java_lang_object != NULL);
	add_class_supertype(type_jarray, type_java_lang_object);
	add_compound_member(type_jarray, superobject_ident, type_java_lang_object);
	ident *length_id = new_id_from_str("length");
	gcj_array_length = add_compound_member(type_jarray, length_id, type_int);

	default_layout_compound_type(type_jarray);
	array_header_size      = get_type_size(type_jarray);
	array_header_end_align = get_type_alignment(type_int);
}
Esempio n. 7
0
unsigned get_type_alignment(type_t *type)
{
	switch (type->kind) {
	case TYPE_ERROR:
		return 0;
	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_COMPLEX:
	case TYPE_ENUM:
		return get_atomic_type_alignment(type->atomic.akind);
	case TYPE_COMPOUND_UNION:
		layout_union_type(&type->compound);
		return type->compound.compound->alignment;
	case TYPE_COMPOUND_STRUCT:
		layout_struct_type(&type->compound);
		return type->compound.compound->alignment;
	case TYPE_FUNCTION:
		/* gcc says 1 here... */
		return 1;
	case TYPE_REFERENCE:
	case TYPE_POINTER:
		return pointer_properties.alignment;
	case TYPE_ARRAY:
		return get_type_alignment(type->array.element_type);
	case TYPE_TYPEDEF: {
		il_alignment_t alignment
			= get_type_alignment(type->typedeft.typedefe->type);
		if (type->typedeft.typedefe->alignment > alignment)
			alignment = type->typedeft.typedefe->alignment;

		return alignment;
	}
	case TYPE_TYPEOF:
		return get_type_alignment(type->typeoft.typeof_type);
	}
	panic("invalid type in get_type_alignment");
}
Esempio n. 8
0
/**
 * Turn a small CopyB node into a series of Load/Store nodes.
 */
static void lower_small_copyb_node(ir_node *irn)
{
	ir_graph      *irg         = get_irn_irg(irn);
	dbg_info      *dbgi        = get_irn_dbg_info(irn);
	ir_node       *block       = get_nodes_block(irn);
	ir_type       *tp          = get_CopyB_type(irn);
	ir_node       *addr_src    = get_CopyB_src(irn);
	ir_node       *addr_dst    = get_CopyB_dst(irn);
	ir_node       *mem         = get_CopyB_mem(irn);
	ir_mode       *mode_ref    = get_irn_mode(addr_src);
	unsigned       mode_bytes  = allow_misalignments ? native_mode_bytes
	                                                 : get_type_alignment(tp);
	unsigned       size        = get_type_size(tp);
	unsigned       offset      = 0;
	bool           is_volatile = get_CopyB_volatility(irn) == volatility_is_volatile;
	ir_cons_flags  flags       = is_volatile ? cons_volatile : cons_none;

	while (offset < size) {
		ir_mode *mode = get_ir_mode(mode_bytes);
		for (; offset + mode_bytes <= size; offset += mode_bytes) {
			ir_mode *mode_ref_int = get_reference_offset_mode(mode_ref);

			/* construct offset */
			ir_node *addr_const = new_r_Const_long(irg, mode_ref_int, offset);
			ir_node *add        = new_r_Add(block, addr_src, addr_const);

			ir_node *load     = new_rd_Load(dbgi, block, mem, add, mode, tp, flags);
			ir_node *load_res = new_r_Proj(load, mode, pn_Load_res);
			ir_node *load_mem = new_r_Proj(load, mode_M, pn_Load_M);

			ir_node *addr_const2 = new_r_Const_long(irg, mode_ref_int, offset);
			ir_node *add2        = new_r_Add(block, addr_dst, addr_const2);

			ir_node *store     = new_rd_Store(dbgi, block, load_mem, add2, load_res, tp, flags);
			ir_node *store_mem = new_r_Proj(store, mode_M, pn_Store_M);

			mem = store_mem;
		}

		mode_bytes /= 2;
	}

	exchange(irn, mem);
}
Esempio n. 9
0
unsigned get_type_alignment_compound(type_t const *const type)
{
	switch (type->kind) {
	case TYPE_ATOMIC:
	case TYPE_COMPLEX:
	case TYPE_IMAGINARY:
	case TYPE_ENUM:
		return atomic_type_properties[type->atomic.akind].struct_alignment;

	case TYPE_TYPEDEF: {
		il_alignment_t const alignment = get_type_alignment_compound(type->typedeft.typedefe->type);
		return MAX(type->typedeft.typedefe->alignment, alignment);
	}

	case TYPE_TYPEOF:
		return get_type_alignment_compound(type->typeoft.typeof_type);

	default:
		return get_type_alignment(type);
	}
}
Esempio n. 10
0
unsigned long WINAPI VARIANT_UserSize(unsigned long *pFlags, unsigned long Start, VARIANT *pvar)
{
    int align;
    TRACE("(%lx,%ld,%p)\n", *pFlags, Start, pvar);
    TRACE("vt=%04x\n", V_VT(pvar));

    ALIGN_LENGTH(Start, 7);
    Start += sizeof(variant_wire_t);
    if(V_VT(pvar) & VT_BYREF)
        Start += 4;

    align = get_type_alignment(pFlags, pvar);
    ALIGN_LENGTH(Start, align);
    if(V_VT(pvar) == (VT_VARIANT | VT_BYREF))
        Start += 4;
    else
        Start += get_type_size(pFlags, pvar);
    Start = wire_extra_user_size(pFlags, Start, pvar);

    TRACE("returning %ld\n", Start);
    return Start;
}
Esempio n. 11
0
unsigned char * WINAPI VARIANT_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar)
{
    variant_wire_t *header;
    unsigned long type_size;
    int align;
    unsigned char *Pos;

    TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar);

    ALIGN_POINTER(Buffer, 7);
    VariantInit(pvar);

    header = (variant_wire_t *)Buffer; 
    
    pvar->n1.n2.vt = header->vt;
    pvar->n1.n2.wReserved1 = header->wReserved1;
    pvar->n1.n2.wReserved2 = header->wReserved2;
    pvar->n1.n2.wReserved3 = header->wReserved3;

    Pos = (unsigned char*)(header + 1);
    type_size = get_type_size(pFlags, pvar);
    align = get_type_alignment(pFlags, pvar);
    ALIGN_POINTER(Pos, align);

    if(header->vt & VT_BYREF)
    {
        Pos += 4;
        pvar->n1.n2.n3.byref = CoTaskMemAlloc(type_size);
        memcpy(pvar->n1.n2.n3.byref, Pos, type_size); 
        if((header->vt & VT_TYPEMASK) != VT_VARIANT)
           Pos += type_size;
        else
            Pos += 4;
    }
    else
    {
        if((header->vt & VT_TYPEMASK) == VT_DECIMAL)
            memcpy(pvar, Pos, type_size);
        else
            memcpy(&pvar->n1.n2.n3, Pos, type_size);
        Pos += type_size;
    }

    if(header->vt & VT_ARRAY)
    {
        if(header->vt & VT_BYREF)
            Pos = LPSAFEARRAY_UserUnmarshal(pFlags, Pos, V_ARRAYREF(pvar));
        else
            Pos = LPSAFEARRAY_UserUnmarshal(pFlags, Pos, &V_ARRAY(pvar));
    }
    else
    {
        switch (header->vt)
        {
        case VT_BSTR:
            V_BSTR(pvar) = NULL;
            Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar));
            break;
        case VT_BSTR | VT_BYREF:
            *V_BSTRREF(pvar) = NULL;
            Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar));
            break;
        case VT_VARIANT | VT_BYREF:
            Pos = VARIANT_UserUnmarshal(pFlags, Pos, V_VARIANTREF(pvar));
            break;
        case VT_DISPATCH | VT_BYREF:
            FIXME("handle DISPATCH by ref\n");
            break;
        case VT_UNKNOWN:
            /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
            Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, pvar);
            break;
        case VT_DISPATCH:
            /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
            Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, pvar);
            break;
        case VT_RECORD:
            FIXME("handle BRECORD by val\n");
            break;
        case VT_RECORD | VT_BYREF:
            FIXME("handle BRECORD by ref\n");
            break;
        }
    }
    return Pos;
}
Esempio n. 12
0
unsigned char * WINAPI VARIANT_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar)
{
    variant_wire_t *header;
    unsigned long type_size;
    int align;
    unsigned char *Pos;

    TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar);
    TRACE("vt=%04x\n", V_VT(pvar));

    ALIGN_POINTER(Buffer, 7);

    header = (variant_wire_t *)Buffer; 

    header->clSize = 0; /* fixed up at the end */
    header->rpcReserverd = 0;
    header->vt = pvar->n1.n2.vt;
    header->wReserved1 = pvar->n1.n2.wReserved1;
    header->wReserved2 = pvar->n1.n2.wReserved2;
    header->wReserved3 = pvar->n1.n2.wReserved3;
    header->switch_is = pvar->n1.n2.vt;
    if(header->switch_is & VT_ARRAY)
        header->switch_is &= ~VT_TYPEMASK;

    Pos = (unsigned char*)(header + 1);
    type_size = get_type_size(pFlags, pvar);
    align = get_type_alignment(pFlags, pvar);
    ALIGN_POINTER(Pos, align);

    if(header->vt & VT_BYREF)
    {
        *(DWORD *)Pos = max(type_size, 4);
        Pos += 4;
        if((header->vt & VT_TYPEMASK) != VT_VARIANT)
        {
            memcpy(Pos, pvar->n1.n2.n3.byref, type_size);
            Pos += type_size;
        }
        else
        {
            *(DWORD*)Pos = 'U' | 's' << 8 | 'e' << 16 | 'r' << 24;
            Pos += 4;
        }
    } 
    else
    {
        if((header->vt & VT_TYPEMASK) == VT_DECIMAL)
            memcpy(Pos, pvar, type_size);
        else
            memcpy(Pos, &pvar->n1.n2.n3, type_size);
        Pos += type_size;
    }

    if(header->vt & VT_ARRAY)
    {
        if(header->vt & VT_BYREF)
            Pos = LPSAFEARRAY_UserMarshal(pFlags, Pos, V_ARRAYREF(pvar));
        else
            Pos = LPSAFEARRAY_UserMarshal(pFlags, Pos, &V_ARRAY(pvar));
    }
    else
    {
        switch (header->vt)
        {
        case VT_BSTR:
            Pos = BSTR_UserMarshal(pFlags, Pos, &V_BSTR(pvar));
            break;
        case VT_BSTR | VT_BYREF:
            Pos = BSTR_UserMarshal(pFlags, Pos, V_BSTRREF(pvar));
            break;
        case VT_VARIANT | VT_BYREF:
            Pos = VARIANT_UserMarshal(pFlags, Pos, V_VARIANTREF(pvar));
            break;
        case VT_DISPATCH | VT_BYREF:
            FIXME("handle DISPATCH by ref\n");
            break;
        case VT_UNKNOWN:
            /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
            Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, pvar);
            break;
        case VT_DISPATCH:
            /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
            Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, pvar);
            break;
        case VT_RECORD:
            FIXME("handle BRECORD by val\n");
            break;
        case VT_RECORD | VT_BYREF:
            FIXME("handle BRECORD by ref\n");
            break;
        }
    }
    header->clSize = ((Pos - Buffer) + 7) >> 3;
    TRACE("marshalled size=%ld\n", header->clSize);
    return Pos;
}