Dan Hipschman : widl: Implement NDR for struct field alignment.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Sep 10 10:17:51 CDT 2007
Module: wine
Branch: master
Commit: 62fb623e14498716730eea347a999256b9707803
URL: http://source.winehq.org/git/wine.git/?a=commit;h=62fb623e14498716730eea347a999256b9707803
Author: Dan Hipschman <dsh at linux.ucla.edu>
Date: Tue Sep 4 11:04:37 2007 -0700
widl: Implement NDR for struct field alignment.
---
dlls/rpcrt4/tests/server.c | 9 +++++++++
dlls/rpcrt4/tests/server.idl | 10 ++++++++++
tools/widl/typegen.c | 40 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c
index 32735a9..b6b2565 100644
--- a/dlls/rpcrt4/tests/server.c
+++ b/dlls/rpcrt4/tests/server.c
@@ -329,6 +329,12 @@ s_sum_toplev_conf_cond(int *x, int a, int b, int c)
return sum;
}
+double
+s_sum_aligns(aligns_t *a)
+{
+ return a->c + a->i + a->s + a->d;
+}
+
void
s_stop(void)
{
@@ -374,6 +380,7 @@ basic_tests(void)
static pvectors_t pvecs = {&vec1, &pvec2};
static sp_inner_t spi = {42};
static sp_t sp = {-13, &spi};
+ static aligns_t aligns = {3, 4, 5, 6.0};
pints_t pints;
ptypes_t ptypes;
int i1, i2, i3, *pi2, *pi3, **ppi3;
@@ -447,6 +454,8 @@ basic_tests(void)
ok(enum_ord(E2) == 2, "RPC enum_ord\n");
ok(enum_ord(E3) == 3, "RPC enum_ord\n");
ok(enum_ord(E4) == 4, "RPC enum_ord\n");
+
+ ok(sum_aligns(&aligns) == 18.0, "RPC sum_aligns\n");
}
static void
diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl
index 59c9477..0a8c0d3 100644
--- a/dlls/rpcrt4/tests/server.idl
+++ b/dlls/rpcrt4/tests/server.idl
@@ -189,5 +189,15 @@ interface IServer
int sum_toplev_conf_2n([size_is(n * 2)] int *x, int n);
int sum_toplev_conf_cond([size_is(c ? a : b)] int *x, int a, int b, int c);
+ typedef struct
+ {
+ char c;
+ int i;
+ short s;
+ double d;
+ } aligns_t;
+
+ double sum_aligns(aligns_t *a);
+
void stop(void);
}
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 2907706..0ec03d9 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -98,6 +98,8 @@ const char *string_of_type(unsigned char type)
case RPC_FC_CARRAY: return "FC_CARRAY";
case RPC_FC_CVARRAY: return "FC_CVARRAY";
case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY";
+ case RPC_FC_ALIGNM4: return "RPC_FC_ALIGNM4";
+ case RPC_FC_ALIGNM8: return "RPC_FC_ALIGNM8";
default:
error("string_of_type: unknown type 0x%02x\n", type);
return NULL;
@@ -682,13 +684,25 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_
static size_t fields_memsize(const var_list_t *fields, unsigned int *align)
{
+ int have_align = FALSE;
size_t size = 0;
const var_t *v;
if (!fields) return 0;
LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
- size += type_memsize(v->type, align);
+ {
+ unsigned int falign = 0;
+ size_t fsize = type_memsize(v->type, &falign);
+ if (!have_align)
+ {
+ *align = falign;
+ have_align = TRUE;
+ }
+ size = (size + (falign - 1)) & ~(falign - 1);
+ size += fsize;
+ }
+ size = (size + (*align - 1)) & ~(*align - 1);
return size;
}
@@ -1508,12 +1522,36 @@ static void write_struct_members(FILE *file, const type_t *type,
unsigned int *corroff, unsigned int *typestring_offset)
{
const var_t *field;
+ unsigned short offset = 0;
if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
{
type_t *ft = field->type;
if (!ft->declarray || !is_conformant_array(ft))
+ {
+ unsigned int align = 0;
+ size_t size = type_memsize(ft, &align);
+ if ((align - 1) & offset)
+ {
+ unsigned char fc = 0;
+ switch (align)
+ {
+ case 4:
+ fc = RPC_FC_ALIGNM4;
+ break;
+ case 8:
+ fc = RPC_FC_ALIGNM8;
+ break;
+ default:
+ error("write_struct_members: cannot align type %d", ft->type);
+ }
+ print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
+ offset = (offset + (align - 1)) & ~(align - 1);
+ *typestring_offset += 1;
+ }
write_member_type(file, ft, field, corroff, typestring_offset);
+ offset += size;
+ }
}
write_end(file, typestring_offset);
More information about the wine-cvs
mailing list