mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Rebase against 00198c4084a61f65f18574d16833d945e50c0614.
This commit is contained in:
parent
506d9500b8
commit
164a792cb2
@ -1,159 +0,0 @@
|
||||
From 8438b605a8c08605a05e60114a549f6e72cda435 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Thu, 14 Jan 2016 15:16:37 +0800
|
||||
Subject: [PATCH] widl: Add support for recursive type references to SLTG
|
||||
typelib generator.
|
||||
|
||||
---
|
||||
tools/widl/write_sltg.c | 66 ++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 46 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c
|
||||
index bb3a6c003d0..b4fd8f38006 100644
|
||||
--- a/tools/widl/write_sltg.c
|
||||
+++ b/tools/widl/write_sltg.c
|
||||
@@ -203,6 +203,12 @@ struct sltg_hrefinfo
|
||||
|
||||
#include "poppack.h"
|
||||
|
||||
+static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type);
|
||||
+static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *type);
|
||||
+static void add_enum_typeinfo(struct sltg_typelib *typelib, type_t *type);
|
||||
+static void add_union_typeinfo(struct sltg_typelib *typelib, type_t *type);
|
||||
+static void add_coclass_typeinfo(struct sltg_typelib *typelib, type_t *type);
|
||||
+
|
||||
static void init_sltg_data(struct sltg_data *data)
|
||||
{
|
||||
data->size = 0;
|
||||
@@ -461,11 +467,6 @@ static void append_data(struct sltg_data *block, const void *data, int size)
|
||||
block->size = new_size;
|
||||
}
|
||||
|
||||
-static void add_typedef_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
-{
|
||||
- error("add_typedef_typeinfo: %s not implemented\n", type->name);
|
||||
-}
|
||||
-
|
||||
static void add_module_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
{
|
||||
error("add_module_typeinfo: %s not implemented\n", type->name);
|
||||
@@ -747,8 +748,8 @@ static int local_href(struct sltg_hrefmap *hrefmap, int typelib_href)
|
||||
return href << 2;
|
||||
}
|
||||
|
||||
-static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset,
|
||||
- int *size_instance, struct sltg_hrefmap *hrefmap)
|
||||
+static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data, type_t *type, short flags,
|
||||
+ short base_offset, int *size_instance, struct sltg_hrefmap *hrefmap)
|
||||
{
|
||||
short vt, vt_flags, desc_offset;
|
||||
|
||||
@@ -840,10 +841,10 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s
|
||||
chat("write_var_desc: vt VT_PTR | 0x0400\n");
|
||||
vt = VT_PTR | 0x0400;
|
||||
append_data(data, &vt, sizeof(vt));
|
||||
- write_var_desc(data, ref, 0, base_offset, size_instance, hrefmap);
|
||||
+ write_var_desc(typelib, data, ref, 0, base_offset, size_instance, hrefmap);
|
||||
}
|
||||
else
|
||||
- write_var_desc(data, ref, 0x0e00, base_offset, size_instance, hrefmap);
|
||||
+ write_var_desc(typelib, data, ref, 0x0e00, base_offset, size_instance, hrefmap);
|
||||
return desc_offset;
|
||||
}
|
||||
|
||||
@@ -862,6 +863,33 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s
|
||||
chat("write_var_desc: VT_USERDEFINED, type %p, name %s, real type %d, href %d\n",
|
||||
type, type->name, type_get_type(type), type->typelib_idx);
|
||||
|
||||
+ if (type->typelib_idx == -1)
|
||||
+ {
|
||||
+ chat("write_var_desc: trying to ref not added type\n");
|
||||
+
|
||||
+ switch (type_get_type(type))
|
||||
+ {
|
||||
+ case TYPE_STRUCT:
|
||||
+ add_structure_typeinfo(typelib, type);
|
||||
+ break;
|
||||
+ case TYPE_INTERFACE:
|
||||
+ add_interface_typeinfo(typelib, type);
|
||||
+ break;
|
||||
+ case TYPE_ENUM:
|
||||
+ add_enum_typeinfo(typelib, type);
|
||||
+ break;
|
||||
+ case TYPE_UNION:
|
||||
+ add_union_typeinfo(typelib, type);
|
||||
+ break;
|
||||
+ case TYPE_COCLASS:
|
||||
+ add_coclass_typeinfo(typelib, type);
|
||||
+ break;
|
||||
+ default:
|
||||
+ error("write_var_desc: VT_USERDEFINED - unhandled type %d\n",
|
||||
+ type_get_type(type));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (type->typelib_idx == -1)
|
||||
error("write_var_desc: trying to ref not added type\n");
|
||||
|
||||
@@ -888,6 +916,8 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
int member_offset, var_count = 0, var_data_size = 0, size_instance = 0;
|
||||
short *type_desc_offset = NULL;
|
||||
|
||||
+ if (type->typelib_idx != -1) return;
|
||||
+
|
||||
chat("add_structure_typeinfo: type %p, type->name %s\n", type, type->name);
|
||||
|
||||
type->typelib_idx = typelib->n_file_blocks;
|
||||
@@ -897,8 +927,6 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
|
||||
init_sltg_data(&data);
|
||||
|
||||
- index_name = add_typeinfo_block(typelib, type, TKIND_RECORD);
|
||||
-
|
||||
if (type_struct_get_fields(type))
|
||||
{
|
||||
int i = 0;
|
||||
@@ -913,13 +941,13 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
{
|
||||
short base_offset;
|
||||
|
||||
- chat("add_structure_typeinfo: var %p, name %s, type %p\n",
|
||||
- var, var->name, var->declspec.type);
|
||||
+ chat("add_structure_typeinfo: var %p (%s), type %p (%s)\n",
|
||||
+ var, var->name, var->declspec.type, var->declspec.type->name);
|
||||
|
||||
init_sltg_data(&var_data[i]);
|
||||
|
||||
base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable);
|
||||
- type_desc_offset[i] = write_var_desc(&var_data[i], var->declspec.type, 0, base_offset, &size_instance, &hrefmap);
|
||||
+ type_desc_offset[i] = write_var_desc(typelib, &var_data[i], var->declspec.type, 0, base_offset, &size_instance, &hrefmap);
|
||||
dump_var_desc(var_data[i].data, var_data[i].size);
|
||||
|
||||
if (var_data[i].size > sizeof(short))
|
||||
@@ -928,6 +956,8 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
}
|
||||
}
|
||||
|
||||
+ index_name = add_typeinfo_block(typelib, type, TKIND_RECORD);
|
||||
+
|
||||
init_typeinfo(&ti, type, TKIND_RECORD, &hrefmap);
|
||||
append_data(&data, &ti, sizeof(ti));
|
||||
|
||||
@@ -1064,12 +1094,8 @@ static void add_statement(struct sltg_typelib *typelib, const statement_t *stmt)
|
||||
|
||||
LIST_FOR_EACH_ENTRY(ref, stmt->u.type_list, typeref_t, entry)
|
||||
{
|
||||
- /* if the type is public then add the typedef, otherwise attempt
|
||||
- * to add the aliased type */
|
||||
- if (is_attr(ref->type->attrs, ATTR_PUBLIC))
|
||||
- add_typedef_typeinfo(typelib, ref->type);
|
||||
- else
|
||||
- add_type_typeinfo(typelib, type_alias_get_aliasee_type(ref->type));
|
||||
+ /* in old style typelibs all types are public */
|
||||
+ add_type_typeinfo(typelib, ref->type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
@ -1,519 +0,0 @@
|
||||
From 9a53aa57ea3bbe2bada3b79f55c165d6d97c34b6 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Tue, 19 Jan 2016 17:01:01 +0800
|
||||
Subject: [PATCH] widl: Add support for interfaces to SLTG typelib generator.
|
||||
|
||||
---
|
||||
tools/widl/write_sltg.c | 431 ++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 417 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c
|
||||
index 2ba5a3c25b0..38a080a319f 100644
|
||||
--- a/tools/widl/write_sltg.c
|
||||
+++ b/tools/widl/write_sltg.c
|
||||
@@ -151,8 +151,8 @@ struct sltg_tail
|
||||
short res1e; /* always 0000 */
|
||||
short cbSizeInstance;
|
||||
short cbAlignment;
|
||||
- short res24; /* always ffff */
|
||||
- short res26; /* always ffff */
|
||||
+ short res24;
|
||||
+ short res26;
|
||||
short cbSizeVft;
|
||||
short res2a; /* always ffff */
|
||||
short res2c; /* always ffff */
|
||||
@@ -201,6 +201,30 @@ struct sltg_hrefinfo
|
||||
char resxx; /* 0xdf */
|
||||
};
|
||||
|
||||
+struct sltg_function
|
||||
+{
|
||||
+ char magic; /* 0x4c, 0xcb or 0x8b with optional SLTG_FUNCTION_FLAGS_PRESENT flag */
|
||||
+ char flags; /* high nibble is INVOKE_KIND, low nibble = 2 */
|
||||
+ short next; /* byte offset from beginning of group to next fn */
|
||||
+ short name; /* Offset within name table to name */
|
||||
+ int dispid; /* dispid */
|
||||
+ short helpcontext; /* helpcontext (again 1 is special) */
|
||||
+ short helpstring; /* helpstring offset to offset */
|
||||
+ short arg_off; /* offset to args from start of block */
|
||||
+ char nacc; /* lowest 3bits are CALLCONV, rest are no of args */
|
||||
+ char retnextopt; /* if 0x80 bit set ret type follows else next WORD
|
||||
+ is offset to ret type. No of optional args is
|
||||
+ middle 6 bits */
|
||||
+ short rettype; /* return type VT_?? or offset to ret type */
|
||||
+ short vtblpos; /* position in vtbl? */
|
||||
+ short funcflags; /* present if magic & 0x20 */
|
||||
+/* Param list starts, repeat next two as required */
|
||||
+#if 0
|
||||
+ WORD name; /* offset to 2nd letter of name */
|
||||
+ WORD+ type; /* VT_ of param */
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
#include "poppack.h"
|
||||
|
||||
static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type);
|
||||
@@ -472,11 +496,6 @@ static void add_module_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
error("add_module_typeinfo: %s not implemented\n", type->name);
|
||||
}
|
||||
|
||||
-static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
-{
|
||||
- error("add_interface_typeinfo: %s not implemented\n", type->name);
|
||||
-}
|
||||
-
|
||||
static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t *type, int kind)
|
||||
{
|
||||
const char *index_name, *other_name;
|
||||
@@ -534,7 +553,7 @@ static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, i
|
||||
ti->misc.flags = 0; /* FIXME */
|
||||
ti->misc.unknown2 = 0x02;
|
||||
ti->misc.typekind = kind;
|
||||
- ti->res1e = -1;
|
||||
+ ti->res1e = 0;
|
||||
|
||||
ti->member_offset = sizeof(*ti);
|
||||
|
||||
@@ -563,10 +582,10 @@ static void init_sltg_tail(struct sltg_tail *tail)
|
||||
tail->cImplTypes = 0;
|
||||
tail->res06 = 0;
|
||||
tail->funcs_off = -1;
|
||||
- tail->vars_off = 0;
|
||||
+ tail->vars_off = -1;
|
||||
tail->impls_off = -1;
|
||||
tail->funcs_bytes = -1;
|
||||
- tail->vars_bytes = 0;
|
||||
+ tail->vars_bytes = -1;
|
||||
tail->impls_bytes = -1;
|
||||
tail->tdescalias_vt = -1;
|
||||
tail->res16 = -1;
|
||||
@@ -813,8 +832,11 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data
|
||||
atype = type_array_get_element_type(atype);
|
||||
}
|
||||
|
||||
- *size_instance += array_size;
|
||||
- size_instance = NULL; /* don't account for element size */
|
||||
+ if (size_instance)
|
||||
+ {
|
||||
+ *size_instance += array_size;
|
||||
+ size_instance = NULL; /* don't account for element size */
|
||||
+ }
|
||||
|
||||
append_data(data, array, size);
|
||||
|
||||
@@ -925,8 +947,6 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
hrefmap.href_count = 0;
|
||||
hrefmap.href = NULL;
|
||||
|
||||
- init_sltg_data(&data);
|
||||
-
|
||||
if (type_struct_get_fields(type))
|
||||
{
|
||||
int i = 0;
|
||||
@@ -956,6 +976,8 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
}
|
||||
}
|
||||
|
||||
+ init_sltg_data(&data);
|
||||
+
|
||||
index_name = add_typeinfo_block(typelib, type, TKIND_RECORD);
|
||||
|
||||
init_typeinfo(&ti, type, TKIND_RECORD, &hrefmap);
|
||||
@@ -1017,6 +1039,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
init_sltg_tail(&tail);
|
||||
|
||||
tail.cVars = var_count;
|
||||
+ tail.vars_off = 0;
|
||||
tail.vars_bytes = var_data_size;
|
||||
tail.cbSizeInstance = size_instance;
|
||||
tail.type_bytes = data.size - member_offset - sizeof(member);
|
||||
@@ -1025,6 +1048,386 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
add_block(typelib, data.data, data.size, index_name);
|
||||
}
|
||||
|
||||
+static importinfo_t *find_importinfo(typelib_t *typelib, const char *name)
|
||||
+{
|
||||
+ importlib_t *importlib;
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY(importlib, &typelib->importlibs, importlib_t, entry)
|
||||
+ {
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < importlib->ntypeinfos; i++)
|
||||
+ {
|
||||
+ if (!strcmp(name, importlib->importinfos[i].name))
|
||||
+ {
|
||||
+ chat("Found %s in importlib list\n", name);
|
||||
+ return &importlib->importinfos[i];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int get_func_flags(const var_t *func, int *dispid, int *invokekind, int *helpcontext, const char **helpstring)
|
||||
+{
|
||||
+ static int dispid_base = 0x60000000;
|
||||
+ const attr_t *attr;
|
||||
+ int flags;
|
||||
+
|
||||
+ *dispid = dispid_base++;
|
||||
+ *invokekind = 1 /* INVOKE_FUNC */;
|
||||
+ *helpcontext = -2;
|
||||
+ *helpstring = NULL;
|
||||
+
|
||||
+ if (!func->attrs) return 0;
|
||||
+
|
||||
+ flags = 0;
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY(attr, func->attrs, const attr_t, entry)
|
||||
+ {
|
||||
+ expr_t *expr = attr->u.pval;
|
||||
+ switch(attr->type)
|
||||
+ {
|
||||
+ case ATTR_BINDABLE:
|
||||
+ flags |= 0x4; /* FUNCFLAG_FBINDABLE */
|
||||
+ break;
|
||||
+ case ATTR_DEFAULTBIND:
|
||||
+ flags |= 0x20; /* FUNCFLAG_FDEFAULTBIND */
|
||||
+ break;
|
||||
+ case ATTR_DEFAULTCOLLELEM:
|
||||
+ flags |= 0x100; /* FUNCFLAG_FDEFAULTCOLLELEM */
|
||||
+ break;
|
||||
+ case ATTR_DISPLAYBIND:
|
||||
+ flags |= 0x10; /* FUNCFLAG_FDISPLAYBIND */
|
||||
+ break;
|
||||
+ case ATTR_HELPCONTEXT:
|
||||
+ *helpcontext = expr->u.lval;
|
||||
+ break;
|
||||
+ case ATTR_HELPSTRING:
|
||||
+ *helpstring = attr->u.pval;
|
||||
+ break;
|
||||
+ case ATTR_HIDDEN:
|
||||
+ flags |= 0x40; /* FUNCFLAG_FHIDDEN */
|
||||
+ break;
|
||||
+ case ATTR_ID:
|
||||
+ *dispid = expr->cval;
|
||||
+ break;
|
||||
+ case ATTR_IMMEDIATEBIND:
|
||||
+ flags |= 0x1000; /* FUNCFLAG_FIMMEDIATEBIND */
|
||||
+ break;
|
||||
+ case ATTR_NONBROWSABLE:
|
||||
+ flags |= 0x400; /* FUNCFLAG_FNONBROWSABLE */
|
||||
+ break;
|
||||
+ case ATTR_PROPGET:
|
||||
+ *invokekind = 0x2; /* INVOKE_PROPERTYGET */
|
||||
+ break;
|
||||
+ case ATTR_PROPPUT:
|
||||
+ *invokekind = 0x4; /* INVOKE_PROPERTYPUT */
|
||||
+ break;
|
||||
+ case ATTR_PROPPUTREF:
|
||||
+ *invokekind = 0x8; /* INVOKE_PROPERTYPUTREF */
|
||||
+ break;
|
||||
+ /* FIXME: FUNCFLAG_FREPLACEABLE */
|
||||
+ case ATTR_REQUESTEDIT:
|
||||
+ flags |= 0x8; /* FUNCFLAG_FREQUESTEDIT */
|
||||
+ break;
|
||||
+ case ATTR_RESTRICTED:
|
||||
+ flags |= 0x1; /* FUNCFLAG_FRESTRICTED */
|
||||
+ break;
|
||||
+ case ATTR_SOURCE:
|
||||
+ flags |= 0x2; /* FUNCFLAG_FSOURCE */
|
||||
+ break;
|
||||
+ case ATTR_UIDEFAULT:
|
||||
+ flags |= 0x200; /* FUNCFLAG_FUIDEFAULT */
|
||||
+ break;
|
||||
+ case ATTR_USESGETLASTERROR:
|
||||
+ flags |= 0x80; /* FUNCFLAG_FUSESGETLASTERROR */
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return flags;
|
||||
+}
|
||||
+
|
||||
+static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, var_t *func,
|
||||
+ int idx, short base_offset, struct sltg_hrefmap *hrefmap)
|
||||
+{
|
||||
+ struct sltg_data ret_data, *arg_data;
|
||||
+ int arg_count = 0, arg_data_size, optional = 0, defaults = 0, old_size;
|
||||
+ int funcflags = 0, dispid, invokekind = 1 /* INVOKE_FUNC */, helpcontext;
|
||||
+ const char *helpstring;
|
||||
+ const var_t *arg;
|
||||
+ short ret_desc_offset, *arg_desc_offset, arg_offset;
|
||||
+ struct sltg_function func_desc;
|
||||
+
|
||||
+ chat("add_func_desc: %s, idx %#x\n", func->name, idx);
|
||||
+
|
||||
+ old_size = data->size;
|
||||
+
|
||||
+ init_sltg_data(&ret_data);
|
||||
+ ret_desc_offset = write_var_desc(typelib, &ret_data, type_function_get_rettype(func->declspec.type),
|
||||
+ 0, base_offset, NULL, hrefmap);
|
||||
+ dump_var_desc(ret_data.data, ret_data.size);
|
||||
+
|
||||
+ arg_data_size = 0;
|
||||
+ arg_offset = base_offset + sizeof(struct sltg_function);
|
||||
+
|
||||
+ if (ret_data.size > sizeof(short))
|
||||
+ {
|
||||
+ arg_data_size += ret_data.size;
|
||||
+ arg_offset += ret_data.size;
|
||||
+ }
|
||||
+
|
||||
+ if (type_function_get_args(func->declspec.type))
|
||||
+ {
|
||||
+ int i = 0;
|
||||
+
|
||||
+ arg_count = list_count(type_function_get_args(func->declspec.type));
|
||||
+
|
||||
+ arg_data = xmalloc(arg_count * sizeof(*arg_data));
|
||||
+ arg_desc_offset = xmalloc(arg_count * sizeof(*arg_desc_offset));
|
||||
+
|
||||
+ arg_offset += arg_count * 2 * sizeof(short);
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY(arg, type_function_get_args(func->declspec.type), const var_t, entry)
|
||||
+ {
|
||||
+ const attr_t *attr;
|
||||
+
|
||||
+ chat("add_func_desc: arg[%d] %p (%s), type %p (%s)\n",
|
||||
+ i, arg, arg->name, arg->declspec.type, arg->declspec.type->name);
|
||||
+
|
||||
+ init_sltg_data(&arg_data[i]);
|
||||
+
|
||||
+ arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->declspec.type, 0, arg_offset, NULL, hrefmap);
|
||||
+ dump_var_desc(arg_data[i].data, arg_data[i].size);
|
||||
+
|
||||
+ if (arg_data[i].size > sizeof(short))
|
||||
+ {
|
||||
+ arg_data_size += arg_data[i].size;
|
||||
+ arg_offset += arg_data[i].size;;
|
||||
+ }
|
||||
+
|
||||
+ i++;
|
||||
+
|
||||
+ if (!arg->attrs) continue;
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY(attr, arg->attrs, const attr_t, entry)
|
||||
+ {
|
||||
+ if (attr->type == ATTR_DEFAULTVALUE)
|
||||
+ defaults++;
|
||||
+ else if(attr->type == ATTR_OPTIONAL)
|
||||
+ optional++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ funcflags = get_func_flags(func, &dispid, &invokekind, &helpcontext, &helpstring);
|
||||
+
|
||||
+ if (base_offset != -1)
|
||||
+ chat("add_func_desc: flags %#x, dispid %#x, invokekind %d, helpcontext %#x, helpstring %s\n",
|
||||
+ funcflags, dispid, invokekind, helpcontext, helpstring);
|
||||
+
|
||||
+ func_desc.magic = 0x6c; /* always write flags to simplify calculations */
|
||||
+ func_desc.flags = (invokekind << 4) | 0x02;
|
||||
+ if (idx & 0x80000000)
|
||||
+ {
|
||||
+ func_desc.next = -1;
|
||||
+ idx &= ~0x80000000;
|
||||
+ }
|
||||
+ else
|
||||
+ func_desc.next = base_offset + sizeof(func_desc) + arg_data_size + arg_count * 2 * sizeof(short);
|
||||
+ func_desc.name = base_offset != -1 ? add_name(typelib, func->name) : -1;
|
||||
+ func_desc.dispid = dispid;
|
||||
+ func_desc.helpcontext = helpcontext;
|
||||
+ func_desc.helpstring = (helpstring && base_offset != -1) ? add_name(typelib, helpstring) : -1;
|
||||
+ func_desc.arg_off = arg_count ? base_offset + sizeof(func_desc) : -1;
|
||||
+ func_desc.nacc = (arg_count << 3) | 4 /* CC_STDCALL */;
|
||||
+ func_desc.retnextopt = (optional << 1);
|
||||
+ if (ret_data.size > sizeof(short))
|
||||
+ {
|
||||
+ func_desc.rettype = base_offset + sizeof(func_desc) + ret_desc_offset;
|
||||
+ if (arg_count)
|
||||
+ func_desc.arg_off += ret_data.size;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ func_desc.retnextopt |= 0x80;
|
||||
+ func_desc.rettype = *(short *)ret_data.data;
|
||||
+ }
|
||||
+ func_desc.vtblpos = idx * pointer_size;
|
||||
+ func_desc.funcflags = funcflags;
|
||||
+
|
||||
+ append_data(data, &func_desc, sizeof(func_desc));
|
||||
+
|
||||
+ arg_offset = base_offset + sizeof(struct sltg_function);
|
||||
+
|
||||
+ if (ret_data.size > sizeof(short))
|
||||
+ {
|
||||
+ append_data(data, ret_data.data, ret_data.size);
|
||||
+ func_desc.arg_off += ret_data.size;
|
||||
+ arg_offset += ret_data.size;
|
||||
+ }
|
||||
+
|
||||
+ if (arg_count)
|
||||
+ {
|
||||
+ int i = 0;
|
||||
+
|
||||
+ arg_offset += arg_count * 2 * sizeof(short);
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY(arg, type_function_get_args(func->declspec.type), const var_t, entry)
|
||||
+ {
|
||||
+ short name, type_offset;
|
||||
+
|
||||
+ name = base_offset != -1 ? add_name(typelib, arg->name) : -1;
|
||||
+ append_data(data, &name, sizeof(name));
|
||||
+
|
||||
+ if (arg_data[i].size > sizeof(short))
|
||||
+ {
|
||||
+ type_offset = (arg_offset + arg_desc_offset[i]);
|
||||
+ arg_offset += arg_data[i].size;
|
||||
+ }
|
||||
+ else
|
||||
+ type_offset = *(short *)arg_data[i].data;
|
||||
+
|
||||
+ append_data(data, &type_offset, sizeof(type_offset));
|
||||
+
|
||||
+ if (base_offset != -1)
|
||||
+ chat("add_func_desc: arg[%d] - name %s (%#x), type_offset %#x\n",
|
||||
+ i, arg->name, name, type_offset);
|
||||
+
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < arg_count; i++)
|
||||
+ {
|
||||
+ if (arg_data[i].size > sizeof(short))
|
||||
+ append_data(data, arg_data[i].data, arg_data[i].size);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return data->size - old_size;
|
||||
+}
|
||||
+
|
||||
+static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface)
|
||||
+{
|
||||
+ const statement_t *stmt_func;
|
||||
+ importinfo_t *ref_importinfo = NULL;
|
||||
+ type_t *inherit;
|
||||
+ struct sltg_data data;
|
||||
+ struct sltg_hrefmap hrefmap;
|
||||
+ const char *index_name;
|
||||
+ struct sltg_typeinfo_header ti;
|
||||
+ struct sltg_member_header member;
|
||||
+ struct sltg_tail tail;
|
||||
+ int member_offset, base_offset, func_count, func_data_size, i;
|
||||
+
|
||||
+ if (iface->typelib_idx != -1) return;
|
||||
+
|
||||
+ chat("add_interface_typeinfo: type %p, type->name %s\n", iface, iface->name);
|
||||
+
|
||||
+ if (!iface->details.iface)
|
||||
+ {
|
||||
+ error("interface %s is referenced but not defined\n", iface->name);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (is_attr(iface->attrs, ATTR_DISPINTERFACE))
|
||||
+ {
|
||||
+ error("support for dispinterface %s is not implemented\n", iface->name);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ inherit = type_iface_get_inherit(iface);
|
||||
+
|
||||
+ if (inherit)
|
||||
+ {
|
||||
+ chat("add_interface_typeinfo: inheriting from base interface %s\n", inherit->name);
|
||||
+
|
||||
+ warning("inheriting from base interface %s is not implemented\n", inherit->name);
|
||||
+
|
||||
+ ref_importinfo = find_importinfo(typelib->typelib, inherit->name);
|
||||
+
|
||||
+ if (!ref_importinfo && type_iface_get_inherit(inherit))
|
||||
+ add_interface_typeinfo(typelib, inherit);
|
||||
+
|
||||
+ if (ref_importinfo)
|
||||
+ error("support for imported interfaces is not implemented\n");
|
||||
+ }
|
||||
+
|
||||
+ /* check typelib_idx again, it could have been added while resolving the parent interface */
|
||||
+ if (iface->typelib_idx != -1) return;
|
||||
+
|
||||
+ iface->typelib_idx = typelib->n_file_blocks;
|
||||
+
|
||||
+ /* pass 1: calculate function descriptions data size */
|
||||
+ hrefmap.href_count = 0;
|
||||
+ hrefmap.href = NULL;
|
||||
+
|
||||
+ init_sltg_data(&data);
|
||||
+
|
||||
+ STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface))
|
||||
+ {
|
||||
+ add_func_desc(typelib, &data, stmt_func->u.var, -1, -1, &hrefmap);
|
||||
+ }
|
||||
+
|
||||
+ func_data_size = data.size;
|
||||
+
|
||||
+ /* pass 2: write function descriptions */
|
||||
+ init_sltg_data(&data);
|
||||
+
|
||||
+ func_count = list_count(type_iface_get_stmts(iface));
|
||||
+
|
||||
+ index_name = add_typeinfo_block(typelib, iface, TKIND_INTERFACE);
|
||||
+
|
||||
+ init_typeinfo(&ti, iface, TKIND_INTERFACE, &hrefmap);
|
||||
+ append_data(&data, &ti, sizeof(ti));
|
||||
+
|
||||
+ write_hrefmap(&data, &hrefmap);
|
||||
+
|
||||
+ member_offset = data.size;
|
||||
+
|
||||
+ member.res00 = 0x0001;
|
||||
+ member.res02 = 0xffff;
|
||||
+ member.res04 = 0x01;
|
||||
+ member.extra = func_data_size;
|
||||
+ append_data(&data, &member, sizeof(member));
|
||||
+
|
||||
+ base_offset = 0;
|
||||
+
|
||||
+ /* inheriting from base interface is not implemented yet
|
||||
+ if (type_iface_get_inherit(iface))
|
||||
+ add_impl_type(typeinfo, type_iface_get_inherit(iface), ref_importinfo);
|
||||
+ */
|
||||
+
|
||||
+ i = 0;
|
||||
+
|
||||
+ STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface))
|
||||
+ {
|
||||
+ if (i == func_count - 1) i |= 0x80000000;
|
||||
+
|
||||
+ base_offset += add_func_desc(typelib, &data, stmt_func->u.var, i, base_offset, &hrefmap);
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ init_sltg_tail(&tail);
|
||||
+
|
||||
+ tail.cFuncs = func_count;
|
||||
+ tail.funcs_off = 0;
|
||||
+ tail.funcs_bytes = func_data_size;
|
||||
+ tail.cbSizeInstance = pointer_size;
|
||||
+ tail.cbAlignment = pointer_size;
|
||||
+ tail.cbSizeVft = func_count * pointer_size;
|
||||
+ tail.type_bytes = data.size - member_offset - sizeof(member);
|
||||
+ tail.res24 = 0;
|
||||
+ tail.res26 = 0;
|
||||
+ append_data(&data, &tail, sizeof(tail));
|
||||
+
|
||||
+ add_block(typelib, data.data, data.size, index_name);
|
||||
+}
|
||||
+
|
||||
static void add_enum_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
{
|
||||
error("add_enum_typeinfo: %s not implemented\n", type->name);
|
||||
--
|
||||
2.17.1
|
||||
|
@ -1,185 +0,0 @@
|
||||
From 95266a585cb4c924250c900a3b8c3c63ebbf0699 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Tue, 19 Jan 2016 18:44:00 +0800
|
||||
Subject: widl: Add support for inherited interfaces to SLTG typelib generator.
|
||||
|
||||
---
|
||||
tools/widl/write_sltg.c | 90 +++++++++++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 73 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c
|
||||
index 556816f..c8a8cfb 100644
|
||||
--- a/tools/widl/write_sltg.c
|
||||
+++ b/tools/widl/write_sltg.c
|
||||
@@ -225,6 +225,22 @@ struct sltg_function
|
||||
#endif
|
||||
};
|
||||
|
||||
+struct sltg_impl_info
|
||||
+{
|
||||
+ short res00;
|
||||
+ short next;
|
||||
+ short res04;
|
||||
+ char impltypeflags;
|
||||
+ char res07;
|
||||
+ short res08;
|
||||
+ short ref;
|
||||
+ short res0c;
|
||||
+ short res0e;
|
||||
+ short res10;
|
||||
+ short res12;
|
||||
+ short pos;
|
||||
+};
|
||||
+
|
||||
#include "poppack.h"
|
||||
|
||||
static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type);
|
||||
@@ -1311,18 +1327,39 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v
|
||||
return data->size - old_size;
|
||||
}
|
||||
|
||||
+static void write_impl_href(struct sltg_data *data, short href)
|
||||
+{
|
||||
+ struct sltg_impl_info impl_info;
|
||||
+
|
||||
+ impl_info.res00 = 0x004a;
|
||||
+ impl_info.next = -1;
|
||||
+ impl_info.res04 = -1;
|
||||
+ impl_info.impltypeflags = 0;
|
||||
+ impl_info.res07 = 0x80;
|
||||
+ impl_info.res08 = 0x0012;
|
||||
+ impl_info.ref = href;
|
||||
+ impl_info.res0c = 0x4001;
|
||||
+ impl_info.res0e = -2; /* 0xfffe */
|
||||
+ impl_info.res10 = -1;
|
||||
+ impl_info.res12 = 0x001d;
|
||||
+ impl_info.pos = 0;
|
||||
+
|
||||
+ append_data(data, &impl_info, sizeof(impl_info));
|
||||
+}
|
||||
+
|
||||
static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface)
|
||||
{
|
||||
const statement_t *stmt_func;
|
||||
importinfo_t *ref_importinfo = NULL;
|
||||
- type_t *inherit;
|
||||
+ short inherit_href = -1;
|
||||
struct sltg_data data;
|
||||
struct sltg_hrefmap hrefmap;
|
||||
const char *index_name;
|
||||
struct sltg_typeinfo_header ti;
|
||||
struct sltg_member_header member;
|
||||
struct sltg_tail tail;
|
||||
- int member_offset, base_offset, func_count, func_data_size, i;
|
||||
+ int member_offset, base_offset, func_data_size, i;
|
||||
+ int func_count, inherited_func_count = 0;
|
||||
|
||||
if (iface->typelib_idx != -1) return;
|
||||
|
||||
@@ -1340,13 +1377,16 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface)
|
||||
return;
|
||||
}
|
||||
|
||||
- inherit = type_iface_get_inherit(iface);
|
||||
+ hrefmap.href_count = 0;
|
||||
+ hrefmap.href = NULL;
|
||||
|
||||
- if (inherit)
|
||||
+ if (type_iface_get_inherit(iface))
|
||||
{
|
||||
- chat("add_interface_typeinfo: inheriting from base interface %s\n", inherit->name);
|
||||
+ type_t *inherit;
|
||||
|
||||
- warning("inheriting from base interface %s is not implemented\n", inherit->name);
|
||||
+ inherit = type_iface_get_inherit(iface);
|
||||
+
|
||||
+ chat("add_interface_typeinfo: inheriting from base interface %s\n", inherit->name);
|
||||
|
||||
ref_importinfo = find_importinfo(typelib->typelib, inherit->name);
|
||||
|
||||
@@ -1355,6 +1395,14 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface)
|
||||
|
||||
if (ref_importinfo)
|
||||
error("support for imported interfaces is not implemented\n");
|
||||
+
|
||||
+ inherit_href = local_href(&hrefmap, inherit->typelib_idx);
|
||||
+
|
||||
+ while (inherit)
|
||||
+ {
|
||||
+ inherited_func_count += list_count(type_iface_get_stmts(inherit));
|
||||
+ inherit = type_iface_get_inherit(inherit);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* check typelib_idx again, it could have been added while resolving the parent interface */
|
||||
@@ -1363,9 +1411,6 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface)
|
||||
iface->typelib_idx = typelib->n_file_blocks;
|
||||
|
||||
/* pass 1: calculate function descriptions data size */
|
||||
- hrefmap.href_count = 0;
|
||||
- hrefmap.href = NULL;
|
||||
-
|
||||
init_sltg_data(&data);
|
||||
|
||||
STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface))
|
||||
@@ -1388,19 +1433,21 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface)
|
||||
write_hrefmap(&data, &hrefmap);
|
||||
|
||||
member_offset = data.size;
|
||||
+ base_offset = 0;
|
||||
|
||||
member.res00 = 0x0001;
|
||||
member.res02 = 0xffff;
|
||||
member.res04 = 0x01;
|
||||
member.extra = func_data_size;
|
||||
+ if (inherit_href != -1)
|
||||
+ {
|
||||
+ member.extra += sizeof(struct sltg_impl_info);
|
||||
+ base_offset += sizeof(struct sltg_impl_info);
|
||||
+ }
|
||||
append_data(&data, &member, sizeof(member));
|
||||
|
||||
- base_offset = 0;
|
||||
-
|
||||
- /* inheriting from base interface is not implemented yet
|
||||
- if (type_iface_get_inherit(iface))
|
||||
- add_impl_type(typeinfo, type_iface_get_inherit(iface), ref_importinfo);
|
||||
- */
|
||||
+ if (inherit_href != -1)
|
||||
+ write_impl_href(&data, inherit_href);
|
||||
|
||||
i = 0;
|
||||
|
||||
@@ -1408,7 +1455,8 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface)
|
||||
{
|
||||
if (i == func_count - 1) i |= 0x80000000;
|
||||
|
||||
- base_offset += add_func_desc(typelib, &data, stmt_func->u.var, i, base_offset, &hrefmap);
|
||||
+ base_offset += add_func_desc(typelib, &data, stmt_func->u.var,
|
||||
+ inherited_func_count + i, base_offset, &hrefmap);
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -1419,10 +1467,18 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface)
|
||||
tail.funcs_bytes = func_data_size;
|
||||
tail.cbSizeInstance = pointer_size;
|
||||
tail.cbAlignment = pointer_size;
|
||||
- tail.cbSizeVft = func_count * pointer_size;
|
||||
+ tail.cbSizeVft = (inherited_func_count + func_count) * pointer_size;
|
||||
tail.type_bytes = data.size - member_offset - sizeof(member);
|
||||
tail.res24 = 0;
|
||||
tail.res26 = 0;
|
||||
+ if (inherit_href != -1)
|
||||
+ {
|
||||
+ tail.cImplTypes++;
|
||||
+ tail.impls_off = 0;
|
||||
+ tail.impls_bytes = 0;
|
||||
+
|
||||
+ tail.funcs_off += sizeof(struct sltg_impl_info);
|
||||
+ }
|
||||
append_data(&data, &tail, sizeof(tail));
|
||||
|
||||
add_block(typelib, data.data, data.size, index_name);
|
||||
--
|
||||
2.6.4
|
||||
|
@ -1 +1 @@
|
||||
8a3b0d7bc317aada750769af8f82762c7001acad
|
||||
00198c4084a61f65f18574d16833d945e50c0614
|
||||
|
Loading…
Reference in New Issue
Block a user