From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 114 +++++++++++++++++++++++++++++++++++++++++ tools/widl/typetree.c | 1 + tools/widl/widltypes.h | 7 +++ 3 files changed, 122 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 4fd20391405..ff23d7ef5c3 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -513,6 +513,18 @@ static void serialize_table_idx( UINT idx, enum table target ) add_bytes( &tables_disk, (const BYTE *)&idx, size ); }
+static enum table resolution_scope_to_table( UINT token ) +{ + switch (token & 0x3) + { + case 0: return TABLE_MODULE; + case 1: return TABLE_MODULEREF; + case 2: return TABLE_ASSEMBLYREF; + case 3: return TABLE_TYPEREF; + default: assert( 0 ); + } +} + static enum table typedef_or_ref_to_table( UINT token ) { switch (token & 0x3) @@ -550,6 +562,33 @@ static void serialize_module_table( void ) serialize_guid_idx( row->encbaseid ); }
+struct typeref_row +{ + UINT scope; + UINT name; + UINT namespace; +}; + +static UINT add_typeref_row( UINT scope, UINT name, UINT namespace ) +{ + struct typeref_row row = { scope, name, namespace }; + return add_row( TABLE_TYPEREF, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_typeref_table( void ) +{ + const struct typeref_row *row = (const struct typeref_row *)tables[TABLE_TYPEREF].ptr; + UINT i; + + for (i = 0; i < tables[TABLE_TYPEREF].count; i++) + { + serialize_table_idx( row->scope, resolution_scope_to_table(row->scope) ); + serialize_string_idx( row->name ); + serialize_string_idx( row->namespace ); + row++; + } +} + struct typedef_row { UINT flags; @@ -660,6 +699,41 @@ static void serialize_assemblyref_table( void ) } }
+static UINT typedef_or_ref( enum table table, UINT row ) +{ + switch (table) + { + case TABLE_TYPEDEF: return row << 2; + case TABLE_TYPEREF: return row << 2 | 1; + case TABLE_TYPESPEC: return row << 2 | 2; + default: assert( 0 ); + } +} + +static UINT resolution_scope( enum table table, UINT row ) +{ + switch (table) + { + case TABLE_MODULE: return row << 2; + case TABLE_MODULEREF: return row << 2 | 1; + case TABLE_ASSEMBLYREF: return row << 2 | 2; + case TABLE_TYPEREF: return row << 2 | 3; + default: assert( 0 ); + } +} + +#define MODULE_ROW 1 +#define MSCORLIB_ROW 1 + +static UINT add_name( type_t *type, UINT *namespace ) +{ + UINT name = add_string( type->name ); + char *str = format_namespace( type->namespace, "", ".", NULL, NULL ); + *namespace = add_string( str ); + free( str ); + return name; +} + enum { LARGE_STRING_HEAP = 0x01, @@ -669,6 +743,43 @@ enum
static char *assembly_name;
+static void add_enum_type_step1( type_t *type ) +{ + UINT name, namespace, scope, typeref; + + name = add_name( type, &namespace ); + + scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW ); + typeref = add_typeref_row( scope, add_string("Enum"), add_string("System") ); + type->md.extends = typedef_or_ref( TABLE_TYPEREF, typeref ); + type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace ); +} + +static void build_tables( const statement_list_t *stmt_list ) +{ + const statement_t *stmt; + + /* Adding a type involves two passes: the first creates various references and the second + uses those references to create the remaining rows. */ + + LIST_FOR_EACH_ENTRY( stmt, stmt_list, const statement_t, entry ) + { + type_t *type = stmt->u.type; + + if (stmt->type != STMT_TYPE) continue; + + switch (type->type_type) + { + case TYPE_ENUM: + add_enum_type_step1( type ); + break; + default: + fprintf( stderr, "Unhandled type %u name '%s'.\n", type->type_type, type->name ); + break; + } + } +} + static void build_table_stream( const statement_list_t *stmts ) { static const GUID guid = { 0x9ddc04c6, 0x04ca, 0x04cc, { 0x52, 0x85, 0x4b, 0x50, 0xb2, 0x60, 0x1d, 0xa8 } }; @@ -690,6 +801,8 @@ static void build_table_stream( const statement_list_t *stmts ) add_module_row( add_string(metadata_name), add_guid(&guid) ); add_assemblyref_row( 0, add_blob(token, sizeof(token)), add_string("mscorlib") );
+ build_tables( stmts ); + for (i = 0; i < TABLE_MAX; i++) if (tables[i].count) tables_header.valid |= (1ull << i);
if (strings.offset >> 16) tables_header.heap_sizes |= LARGE_STRING_HEAP; @@ -702,6 +815,7 @@ static void build_table_stream( const statement_list_t *stmts ) if (tables[i].count) add_bytes( &tables_disk, (const BYTE *)&tables[i].count, sizeof(tables[i].count) );
serialize_module_table(); + serialize_typeref_table(); serialize_typedef_table(); serialize_assembly_table(); serialize_assemblyref_table(); diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index af41906c42b..2f67545393e 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -56,6 +56,7 @@ type_t *make_type(enum type_type type) t->param_name = NULL; t->short_name = NULL; memset(&t->details, 0, sizeof(t->details)); + memset(&t->md, 0, sizeof(t->md)); t->typestring_offset = 0; t->ptrdesc = 0; t->ignore = (parse_only != 0); diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 5ee1323793d..3c8b1179d96 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -496,6 +496,12 @@ enum type_type TYPE_DELEGATE, };
+struct metadata +{ + unsigned int ref; + unsigned int extends; +}; + struct _type_t { const char *name; /* C++ name with parameters in brackets */ struct namespace *namespace; @@ -527,6 +533,7 @@ struct _type_t { unsigned int typestring_offset; unsigned int ptrdesc; /* used for complex structs */ int typelib_idx; + struct metadata md; struct location where; unsigned int ignore : 1; unsigned int defined : 1;
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 251 +++++++++++++++++++++++++++++++++++++++++ tools/widl/widltypes.h | 1 + 2 files changed, 252 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index ff23d7ef5c3..d3e0bb4d074 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -479,6 +479,11 @@ static void add_bytes( struct buffer *buf, const BYTE *data, UINT size ) buf->offset += size; }
+static void serialize_byte( BYTE value ) +{ + add_bytes( &tables_disk, (const BYTE *)&value, sizeof(value) ); +} + static void serialize_ushort( USHORT value ) { add_bytes( &tables_disk, (const BYTE *)&value, sizeof(value) ); @@ -536,6 +541,17 @@ static enum table typedef_or_ref_to_table( UINT token ) } }
+static enum table has_constant_to_table( UINT token ) +{ + switch (token & 0x3) + { + case 0: return TABLE_FIELD; + case 1: return TABLE_PARAM; + case 2: return TABLE_PROPERTY; + default: assert( 0 ); + } +} + struct module_row { USHORT generation; @@ -626,6 +642,73 @@ static void serialize_typedef_table( void ) } }
+struct field_row +{ + USHORT flags; + UINT name; + UINT signature; +}; + +static UINT add_field_row( UINT flags, UINT name, UINT signature ) +{ + struct field_row row = { flags, name, signature }; + return add_row( TABLE_FIELD, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_field_table( void ) +{ + const struct field_row *row = (const struct field_row *)tables[TABLE_FIELD].ptr; + UINT i; + + for (i = 0; i < tables[TABLE_FIELD].count; i++) + { + serialize_ushort( row->flags ); + serialize_string_idx( row->name ); + serialize_blob_idx( row->signature ); + row++; + } +} + +struct constant_row +{ + BYTE type; + BYTE padding; + UINT parent; + UINT value; +}; + +static UINT add_constant_row( BYTE type, UINT parent, UINT value ) +{ + struct constant_row row = { type, 0, parent, value }; + return add_row( TABLE_CONSTANT, (const BYTE *)&row, sizeof(row) ); +} + +static int cmp_constant_row( const void *a, const void *b ) +{ + const struct constant_row *row = a, *row2 = b; + if (row->parent > row2->parent) return 1; + if (row->parent < row2->parent) return -1; + return 0; +} + +/* sorted by parent */ +static void serialize_constant_table( void ) +{ + const struct constant_row *row = (const struct constant_row *)tables[TABLE_CONSTANT].ptr; + UINT i; + + qsort( tables[TABLE_CONSTANT].ptr, tables[TABLE_CONSTANT].count, sizeof(*row), cmp_constant_row ); + + for (i = 0; i < tables_idx[TABLE_CONSTANT].count; i++) + { + serialize_byte( row->type ); + serialize_byte( row->padding ); + serialize_table_idx( row->parent, has_constant_to_table(row->parent) ); + serialize_blob_idx( row->value ); + row++; + } +} + struct assembly_row { UINT hashalgid; @@ -722,6 +805,118 @@ static UINT resolution_scope( enum table table, UINT row ) } }
+static UINT has_constant( enum table table, UINT row ) +{ + switch (table) + { + case TABLE_FIELD: return row << 2; + case TABLE_PARAM: return row << 2 | 1; + case TABLE_PROPERTY: return row << 2 | 2; + default: assert( 0 ); + } +} + +enum element_type +{ + ELEMENT_TYPE_END = 0x00, + ELEMENT_TYPE_VOID = 0x01, + ELEMENT_TYPE_BOOLEAN = 0x02, + ELEMENT_TYPE_CHAR = 0x03, + ELEMENT_TYPE_I1 = 0x04, + ELEMENT_TYPE_U1 = 0x05, + ELEMENT_TYPE_I2 = 0x06, + ELEMENT_TYPE_U2 = 0x07, + ELEMENT_TYPE_I4 = 0x08, + ELEMENT_TYPE_U4 = 0x09, + ELEMENT_TYPE_I8 = 0x0a, + ELEMENT_TYPE_U8 = 0x0b, + ELEMENT_TYPE_R4 = 0x0c, + ELEMENT_TYPE_R8 = 0x0d, + ELEMENT_TYPE_STRING = 0x0e, + ELEMENT_TYPE_PTR = 0x0f, + ELEMENT_TYPE_BYREF = 0x10, + ELEMENT_TYPE_VALUETYPE = 0x11, + ELEMENT_TYPE_CLASS = 0x12, + ELEMENT_TYPE_VAR = 0x13, + ELEMENT_TYPE_ARRAY = 0x14, + ELEMENT_TYPE_GENERICINST = 0x15, + ELEMENT_TYPE_TYPEDBYREF = 0x16, + ELEMENT_TYPE_I = 0x18, + ELEMENT_TYPE_U = 0x19, + ELEMENT_TYPE_FNPTR = 0x1b, + ELEMENT_TYPE_OBJECT = 0x1c, + ELEMENT_TYPE_SZARRAY = 0x1d, + ELEMENT_TYPE_MVAR = 0x1e, + ELEMENT_TYPE_CMOD_REQD = 0x1f, + ELEMENT_TYPE_CMOD_OPT = 0x20, + ELEMENT_TYPE_INTERNAL = 0x21, + ELEMENT_TYPE_MODIFIER = 0x40, + ELEMENT_TYPE_SENTINEL = 0x41, + ELEMENT_TYPE_PINNED = 0x45 +}; + +enum +{ + TYPE_ATTR_PUBLIC = 0x000001, + TYPE_ATTR_NESTEDPUBLIC = 0x000002, + TYPE_ATTR_NESTEDPRIVATE = 0x000003, + TYPE_ATTR_NESTEDFAMILY = 0x000004, + TYPE_ATTR_NESTEDASSEMBLY = 0x000005, + TYPE_ATTR_NESTEDFAMANDASSEM = 0x000006, + TYPE_ATTR_NESTEDFAMORASSEM = 0x000007, + TYPE_ATTR_SEQUENTIALLAYOUT = 0x000008, + TYPE_ATTR_EXPLICITLAYOUT = 0x000010, + TYPE_ATTR_INTERFACE = 0x000020, + TYPE_ATTR_ABSTRACT = 0x000080, + TYPE_ATTR_SEALED = 0x000100, + TYPE_ATTR_SPECIALNAME = 0x000400, + TYPE_ATTR_RTSPECIALNAME = 0x000800, + TYPE_ATTR_IMPORT = 0x001000, + TYPE_ATTR_SERIALIZABLE = 0x002000, + TYPE_ATTR_UNKNOWN = 0x004000, + TYPE_ATTR_UNICODECLASS = 0x010000, + TYPE_ATTR_AUTOCLASS = 0x020000, + TYPE_ATTR_CUSTOMFORMATCLASS = 0x030000, + TYPE_ATTR_HASSECURITY = 0x040000, + TYPE_ATTR_BEFOREFIELDINIT = 0x100000 +}; + +enum +{ + FIELD_ATTR_PRIVATE = 0x0001, + FIELD_ATTR_FAMANDASSEM = 0x0002, + FIELD_ATTR_ASSEMBLY = 0x0003, + FIELD_ATTR_FAMILY = 0x0004, + FIELD_ATTR_FAMORASSEM = 0x0005, + FIELD_ATTR_PUBLIC = 0x0006, + FIELD_ATTR_STATIC = 0x0010, + FIELD_ATTR_INITONLY = 0x0020, + FIELD_ATTR_LITERAL = 0x0040, + FIELD_ATTR_NOTSERIALIZED = 0x0080, + FIELD_ATTR_HASFIELDRVA = 0x0100, + FIELD_ATTR_SPECIALNAME = 0x0200, + FIELD_ATTR_RTSPECIALNAME = 0x0400, + FIELD_ATTR_HASFIELDMARSHAL = 0x1000, + FIELD_ATTR_PINVOKEIMPL = 0x2000, + FIELD_ATTR_HASDEFAULT = 0x8000 +}; + +enum +{ + SIG_TYPE_DEFAULT = 0x00, + SIG_TYPE_C = 0x01, + SIG_TYPE_STDCALL = 0x02, + SIG_TYPE_THISCALL = 0x03, + SIG_TYPE_FASTCALL = 0x04, + SIG_TYPE_VARARG = 0x05, + SIG_TYPE_FIELD = 0x06, + SIG_TYPE_LOCALSIG = 0x07, + SIG_TYPE_PROPERTY = 0x08, + SIG_TYPE_GENERIC = 0x10, + SIG_TYPE_HASTHIS = 0x20, + SIG_TYPE_EXPLICITTHIS = 0x40 +}; + #define MODULE_ROW 1 #define MSCORLIB_ROW 1
@@ -734,6 +929,16 @@ static UINT add_name( type_t *type, UINT *namespace ) return name; }
+static UINT make_field_value_sig( UINT token, BYTE *buf ) +{ + UINT len = 2; + + buf[0] = SIG_TYPE_FIELD; + buf[1] = ELEMENT_TYPE_VALUETYPE; + len += encode_int( token, buf + 2 ); + return len; +} + enum { LARGE_STRING_HEAP = 0x01, @@ -755,6 +960,34 @@ static void add_enum_type_step1( type_t *type ) type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace ); }
+static void add_enum_type_step2( type_t *type ) +{ + BYTE sig_value[] = { SIG_TYPE_FIELD, ELEMENT_TYPE_I4 }; + UINT name, namespace, field, parent, sig_size; + BYTE sig_field[32]; + const var_t *var; + + name = add_name( type, &namespace ); + + field = add_field_row( FIELD_ATTR_PRIVATE | FIELD_ATTR_SPECIALNAME | FIELD_ATTR_RTSPECIALNAME, + add_string("value__"), add_blob(sig_value, sizeof(sig_value)) ); + + type->md.def = add_typedef_row( TYPE_ATTR_PUBLIC | TYPE_ATTR_SEALED | TYPE_ATTR_UNKNOWN, name, namespace, + type->md.extends, field, 1 ); + + sig_size = make_field_value_sig( typedef_or_ref(TABLE_TYPEREF, type->md.ref), sig_field ); + + LIST_FOR_EACH_ENTRY( var, type_enum_get_values(type), const var_t, entry ) + { + int val = var->eval->u.integer.value; + + field = add_field_row( FIELD_ATTR_PUBLIC | FIELD_ATTR_LITERAL | FIELD_ATTR_STATIC | FIELD_ATTR_HASDEFAULT, + add_string(var->name), add_blob(sig_field, sig_size) ); + parent = has_constant( TABLE_FIELD, field ); + add_constant_row( sig_value[1], parent, add_blob((const BYTE *)&val, sizeof(val)) ); + } +} + static void build_tables( const statement_list_t *stmt_list ) { const statement_t *stmt; @@ -778,6 +1011,22 @@ static void build_tables( const statement_list_t *stmt_list ) break; } } + + LIST_FOR_EACH_ENTRY( stmt, stmt_list, const statement_t, entry ) + { + type_t *type = stmt->u.type; + + if (stmt->type != STMT_TYPE) continue; + + switch (type->type_type) + { + case TYPE_ENUM: + add_enum_type_step2( type ); + break; + default: + break; + } + } }
static void build_table_stream( const statement_list_t *stmts ) @@ -817,6 +1066,8 @@ static void build_table_stream( const statement_list_t *stmts ) serialize_module_table(); serialize_typeref_table(); serialize_typedef_table(); + serialize_field_table(); + serialize_constant_table(); serialize_assembly_table(); serialize_assemblyref_table(); } diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 3c8b1179d96..4e707189b7e 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -499,6 +499,7 @@ enum type_type struct metadata { unsigned int ref; + unsigned int def; unsigned int extends; };
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 197 +++++++++++++++++++++++++++++++++++++++++ tools/widl/widltypes.h | 16 ++++ 2 files changed, 213 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index d3e0bb4d074..a0ef838e888 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -541,6 +541,19 @@ static enum table typedef_or_ref_to_table( UINT token ) } }
+static enum table memberref_parent_to_table( UINT token ) +{ + switch (token & 0x7) + { + case 0: return TABLE_TYPEDEF; + case 1: return TABLE_TYPEREF; + case 2: return TABLE_MODULEREF; + case 3: return TABLE_METHODDEF; + case 4: return TABLE_TYPESPEC; + default: assert( 0 ); + } +} + static enum table has_constant_to_table( UINT token ) { switch (token & 0x3) @@ -552,6 +565,42 @@ static enum table has_constant_to_table( UINT token ) } }
+static enum table has_customattribute_to_table( UINT token ) +{ + switch (token & 0x1f) + { + case 0: return TABLE_METHODDEF; + case 1: return TABLE_FIELD; + case 2: return TABLE_TYPEREF; + case 3: return TABLE_TYPEDEF; + case 4: return TABLE_PARAM; + case 5: return TABLE_INTERFACEIMPL; + case 6: return TABLE_MEMBERREF; + case 7: return TABLE_MODULE; + case 9: return TABLE_PROPERTY; + case 10: return TABLE_EVENT; + case 11: return TABLE_STANDALONESIG; + case 12: return TABLE_MODULEREF; + case 13: return TABLE_TYPESPEC; + case 14: return TABLE_ASSEMBLY; + case 15: return TABLE_ASSEMBLYREF; + case 16: return TABLE_FILE; + case 17: return TABLE_EXPORTEDTYPE; + case 18: return TABLE_MANIFESTRESOURCE; + default: assert( 0 ); + } +} + +static enum table customattribute_type_to_table( UINT token ) +{ + switch (token & 0x7) + { + case 2: return TABLE_METHODDEF; + case 3: return TABLE_MEMBERREF; + default: assert( 0 ); + } +} + struct module_row { USHORT generation; @@ -669,6 +718,33 @@ static void serialize_field_table( void ) } }
+struct memberref_row +{ + UINT class; + UINT name; + UINT signature; +}; + +static UINT add_memberref_row( UINT class, UINT name, UINT signature ) +{ + struct memberref_row row = { class, name, signature }; + return add_row( TABLE_MEMBERREF, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_memberref_table( void ) +{ + const struct memberref_row *row = (const struct memberref_row *)tables[TABLE_MEMBERREF].ptr; + UINT i; + + for (i = 0; i < tables[TABLE_MEMBERREF].count; i++) + { + serialize_table_idx( row->class, memberref_parent_to_table(row->class) ); + serialize_string_idx( row->name ); + serialize_blob_idx( row->signature ); + row++; + } +} + struct constant_row { BYTE type; @@ -709,6 +785,45 @@ static void serialize_constant_table( void ) } }
+struct customattribute_row +{ + UINT parent; + UINT type; + UINT value; +}; + +static UINT add_customattribute_row( UINT parent, UINT type, UINT value ) +{ + struct customattribute_row row = { parent, type, value }; + return add_row( TABLE_CUSTOMATTRIBUTE, (const BYTE *)&row, sizeof(row) ); +} + +static int cmp_customattribute_row( const void *a, const void *b ) +{ + const struct customattribute_row *row = a, *row2 = b; + if (row->parent > row2->parent) return 1; + if (row->parent < row2->parent) return -1; + return 0; +} + +/* sorted by parent */ +static void serialize_customattribute_table( void ) +{ + const struct customattribute_row *row = (const struct customattribute_row *)tables[TABLE_CUSTOMATTRIBUTE].ptr; + UINT i; + + qsort( tables[TABLE_CUSTOMATTRIBUTE].ptr, tables[TABLE_CUSTOMATTRIBUTE].count, sizeof(*row), + cmp_customattribute_row ); + + for (i = 0; i < tables_idx[TABLE_CUSTOMATTRIBUTE].count; i++) + { + serialize_table_idx( row->parent, has_customattribute_to_table(row->parent) ); + serialize_table_idx( row->type, customattribute_type_to_table(row->type) ); + serialize_blob_idx( row->value ); + row++; + } +} + struct assembly_row { UINT hashalgid; @@ -816,6 +931,55 @@ static UINT has_constant( enum table table, UINT row ) } }
+static UINT memberref_parent( enum table table, UINT row ) +{ + switch (table) + { + case TABLE_TYPEDEF: return row << 3; + case TABLE_TYPEREF: return row << 3 | 1; + case TABLE_MODULEREF: return row << 3 | 2; + case TABLE_METHODDEF: return row << 3 | 3; + case TABLE_TYPESPEC: return row << 3 | 4; + default: assert( 0 ); + } +} + +static UINT has_customattribute( enum table table, UINT row ) +{ + switch (table) + { + case TABLE_METHODDEF: return row << 5; + case TABLE_FIELD: return row << 5 | 1; + case TABLE_TYPEREF: return row << 5 | 2; + case TABLE_TYPEDEF: return row << 5 | 3; + case TABLE_PARAM: return row << 5 | 4; + case TABLE_INTERFACEIMPL: return row << 5 | 5; + case TABLE_MEMBERREF: return row << 5 | 6; + case TABLE_MODULE: return row << 5 | 7; + case TABLE_PROPERTY: return row << 5 | 9; + case TABLE_EVENT: return row << 5 | 10; + case TABLE_STANDALONESIG: return row << 5 | 11; + case TABLE_MODULEREF: return row << 5 | 12; + case TABLE_TYPESPEC: return row << 5 | 13; + case TABLE_ASSEMBLY: return row << 5 | 14; + case TABLE_ASSEMBLYREF: return row << 5 | 15; + case TABLE_FILE: return row << 5 | 16; + case TABLE_EXPORTEDTYPE: return row << 5 | 17; + case TABLE_MANIFESTRESOURCE: return row << 5 | 18; + default: assert( 0 ); + } +} + +static UINT customattribute_type( enum table table, UINT row ) +{ + switch (table) + { + case TABLE_METHODDEF: return row << 3 | 2; + case TABLE_MEMBERREF: return row << 3 | 3; + default: assert( 0 ); + } +} + enum element_type { ELEMENT_TYPE_END = 0x00, @@ -948,6 +1112,31 @@ enum
static char *assembly_name;
+static void add_flags_attr_step1( type_t *type ) +{ + static const BYTE sig[] = { SIG_TYPE_HASTHIS, 0, ELEMENT_TYPE_VOID }; + UINT scope, typeref, class; + + if (!is_attr( type->attrs, ATTR_FLAGS )) return; + + scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW ); + typeref = add_typeref_row( scope, add_string("FlagsAttribute"), add_string("System") ); + class = memberref_parent( TABLE_TYPEREF, typeref ); + type->md.member[MD_ATTR_FLAGS] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) ); +} + +static void add_flags_attr_step2( type_t *type ) +{ + static const BYTE value[] = { 0x01, 0x00, 0x00, 0x00 }; + UINT parent, attr_type; + + if (!is_attr( type->attrs, ATTR_FLAGS )) return; + + parent = has_customattribute( TABLE_TYPEDEF, type->md.def ); + attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_FLAGS] ); + add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) ); +} + static void add_enum_type_step1( type_t *type ) { UINT name, namespace, scope, typeref; @@ -958,6 +1147,8 @@ static void add_enum_type_step1( type_t *type ) typeref = add_typeref_row( scope, add_string("Enum"), add_string("System") ); type->md.extends = typedef_or_ref( TABLE_TYPEREF, typeref ); type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace ); + + add_flags_attr_step1( type ); }
static void add_enum_type_step2( type_t *type ) @@ -967,6 +1158,8 @@ static void add_enum_type_step2( type_t *type ) BYTE sig_field[32]; const var_t *var;
+ if (is_attr( type->attrs, ATTR_FLAGS )) sig_value[1] = ELEMENT_TYPE_U4; + name = add_name( type, &namespace );
field = add_field_row( FIELD_ATTR_PRIVATE | FIELD_ATTR_SPECIALNAME | FIELD_ATTR_RTSPECIALNAME, @@ -986,6 +1179,8 @@ static void add_enum_type_step2( type_t *type ) parent = has_constant( TABLE_FIELD, field ); add_constant_row( sig_value[1], parent, add_blob((const BYTE *)&val, sizeof(val)) ); } + + add_flags_attr_step2( type ); }
static void build_tables( const statement_list_t *stmt_list ) @@ -1067,7 +1262,9 @@ static void build_table_stream( const statement_list_t *stmts ) serialize_typeref_table(); serialize_typedef_table(); serialize_field_table(); + serialize_memberref_table(); serialize_constant_table(); + serialize_customattribute_table(); serialize_assembly_table(); serialize_assemblyref_table(); } diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 4e707189b7e..a0d3dba82ad 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -496,11 +496,27 @@ enum type_type TYPE_DELEGATE, };
+enum +{ + MD_ATTR_CONTRACT, + MD_ATTR_FLAGS, + MD_ATTR_APICONTRACT, + MD_ATTR_CONTRACTVERSION, + MD_ATTR_UUID, + MD_ATTR_EXCLUSIVETO, + MD_ATTR_STATIC, + MD_ATTR_ACTIVATABLE, + MD_ATTR_THREADING, + MD_ATTR_MARSHALINGBEHAVIOR, + MD_ATTR_MAX, +}; + struct metadata { unsigned int ref; unsigned int def; unsigned int extends; + unsigned int member[MD_ATTR_MAX]; };
struct _type_t {
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 69 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index a0ef838e888..14a8ce158ac 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1112,6 +1112,73 @@ enum
static char *assembly_name;
+static UINT make_member_sig( UINT token, BYTE *buf ) +{ + UINT len = 4; + + buf[0] = SIG_TYPE_HASTHIS; + buf[1] = 2; + buf[2] = ELEMENT_TYPE_VOID; + buf[3] = ELEMENT_TYPE_CLASS; + len += encode_int( token, buf + 4 ); + buf[len++] = ELEMENT_TYPE_U4; + return len; +} + +static UINT make_contract_value( const type_t *type, BYTE *buf ) +{ + const expr_t *contract = get_attrp( type->attrs, ATTR_CONTRACT ); + char *name = format_namespace( contract->u.tref.type->namespace, "", ".", contract->u.tref.type->name, NULL ); + UINT version = contract->ref->u.integer.value, len = strlen( name ); + + buf[0] = 1; + buf[1] = 0; + buf[2] = len; + memcpy( buf + 3, name, len ); + len += 3; + memcpy( buf + len, &version, sizeof(version) ); + len += sizeof(version); + buf[len++] = 0; + buf[len++] = 0; + + free( name ); + return len; +} + +static void add_contract_attr_step1( type_t *type ) +{ + UINT assemblyref, scope, typeref, typeref_type, class, sig_size; + BYTE sig[32]; + + if (!is_attr( type->attrs, ATTR_CONTRACT )) return; + + add_assemblyref_row( 0x200, 0, add_string("windowscontracts") ); + assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") ); + + scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW ); + typeref_type = add_typeref_row( scope, add_string("Type"), add_string("System") ); + + scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref ); + typeref = add_typeref_row( scope, add_string("ContractVersionAttribute"), add_string("Windows.Foundation.Metadata") ); + + class = memberref_parent( TABLE_TYPEREF, typeref ); + sig_size = make_member_sig( typedef_or_ref(TABLE_TYPEREF, typeref_type), sig ); + type->md.member[MD_ATTR_CONTRACT] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) ); +} + +static void add_contract_attr_step2( type_t *type ) +{ + UINT parent, attr_type, value_size; + BYTE value[256 + sizeof(UINT) + 5]; + + if (!is_attr( type->attrs, ATTR_CONTRACT )) return; + + parent = has_customattribute( TABLE_TYPEDEF, type->md.def ); + attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_CONTRACT] ); + value_size = make_contract_value( type, value ); + add_customattribute_row( parent, attr_type, add_blob(value, value_size) ); +} + static void add_flags_attr_step1( type_t *type ) { static const BYTE sig[] = { SIG_TYPE_HASTHIS, 0, ELEMENT_TYPE_VOID }; @@ -1148,6 +1215,7 @@ static void add_enum_type_step1( type_t *type ) type->md.extends = typedef_or_ref( TABLE_TYPEREF, typeref ); type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace );
+ add_contract_attr_step1( type ); add_flags_attr_step1( type ); }
@@ -1180,6 +1248,7 @@ static void add_enum_type_step2( type_t *type ) add_constant_row( sig_value[1], parent, add_blob((const BYTE *)&val, sizeof(val)) ); }
+ add_contract_attr_step2( type ); add_flags_attr_step2( type ); }
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 42 ++++++++++++++++++++++++++++++++++++++++++ tools/widl/widltypes.h | 1 + 2 files changed, 43 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 14a8ce158ac..1aa9f01deb8 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1145,6 +1145,18 @@ static UINT make_contract_value( const type_t *type, BYTE *buf ) return len; }
+static UINT make_version_value( const type_t *type, BYTE *buf ) +{ + UINT version = get_attrv( type->attrs, ATTR_VERSION ); + + buf[0] = 1; + buf[1] = 0; + buf[2] = is_attr( type->attrs, ATTR_VERSION ) ? 0 : 1; + buf[3] = 0; + memcpy( buf + 4, &version, sizeof(version) ); + return 8; +} + static void add_contract_attr_step1( type_t *type ) { UINT assemblyref, scope, typeref, typeref_type, class, sig_size; @@ -1179,6 +1191,34 @@ static void add_contract_attr_step2( type_t *type ) add_customattribute_row( parent, attr_type, add_blob(value, value_size) ); }
+static void add_version_attr_step1( type_t *type ) +{ + static const BYTE sig[] = { SIG_TYPE_HASTHIS, 1, ELEMENT_TYPE_VOID, ELEMENT_TYPE_U4 }; + UINT assemblyref, scope, typeref, class; + + if (!is_attr( type->attrs, ATTR_VERSION ) && is_attr( type->attrs, ATTR_CONTRACT )) return; + + assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") ); + scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref ); + + typeref = add_typeref_row( scope, add_string("VersionAttribute"), add_string("Windows.Foundation.Metadata") ); + class = memberref_parent( TABLE_TYPEREF, typeref ); + type->md.member[MD_ATTR_VERSION] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) ); +} + +static void add_version_attr_step2( type_t *type ) +{ + UINT parent, attr_type, value_size; + BYTE value[8]; + + if (!is_attr( type->attrs, ATTR_VERSION ) && is_attr( type->attrs, ATTR_CONTRACT )) return; + + parent = has_customattribute( TABLE_TYPEDEF, type->md.def ); + attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_VERSION] ); + value_size = make_version_value( type, value ); + add_customattribute_row( parent, attr_type, add_blob(value, value_size) ); +} + static void add_flags_attr_step1( type_t *type ) { static const BYTE sig[] = { SIG_TYPE_HASTHIS, 0, ELEMENT_TYPE_VOID }; @@ -1215,6 +1255,7 @@ static void add_enum_type_step1( type_t *type ) type->md.extends = typedef_or_ref( TABLE_TYPEREF, typeref ); type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace );
+ add_version_attr_step1( type ); add_contract_attr_step1( type ); add_flags_attr_step1( type ); } @@ -1248,6 +1289,7 @@ static void add_enum_type_step2( type_t *type ) add_constant_row( sig_value[1], parent, add_blob((const BYTE *)&val, sizeof(val)) ); }
+ add_version_attr_step2( type ); add_contract_attr_step2( type ); add_flags_attr_step2( type ); } diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index a0d3dba82ad..c76dea97a6c 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -502,6 +502,7 @@ enum MD_ATTR_FLAGS, MD_ATTR_APICONTRACT, MD_ATTR_CONTRACTVERSION, + MD_ATTR_VERSION, MD_ATTR_UUID, MD_ATTR_EXCLUSIVETO, MD_ATTR_STATIC,
This merge request was approved by Rémi Bernon.
This merge request was approved by Huw Davies.