widl: Update to current Wine version. Signed-off-by: Jacek Caban <jacek@codeweavers.com>
diff --git a/mingw-w64-tools/widl/Makefile.am b/mingw-w64-tools/widl/Makefile.am index d53cf87..74574d2 100644 --- a/mingw-w64-tools/widl/Makefile.am +++ b/mingw-w64-tools/widl/Makefile.am
@@ -58,6 +58,6 @@ include/winnt.rh widl_CPPFLAGS = -I$(top_srcdir)/include -DINCLUDEDIR=\""@WIDL_INCLUDEDIR@"\" -DBIN_TO_INCLUDEDIR=\""@BIN_TO_INCLUDEDIR@"\" -DBIN_TO_DLLDIR=\""@BIN_TO_INCLUDEDIR@"\" -DDLLDIR="\"@prefix@/lib\"" -widl_CFLAGS = -O3 -g -Wall -Wformat -Wpacked -Wmissing-declarations -Wimplicit-function-declaration -Wmissing-prototypes -Wstrict-aliasing=2 +widl_CFLAGS = -O3 -g -Wall -Wformat -Wpacked -Wmissing-declarations -Wimplicit-function-declaration -Wmissing-prototypes DISTCHECK_CONFIGURE_FLAGS = --host=$(host) --target=$(target)
diff --git a/mingw-w64-tools/widl/Makefile.in b/mingw-w64-tools/widl/Makefile.in index 5e8b7bc..8d65d92 100644 --- a/mingw-w64-tools/widl/Makefile.in +++ b/mingw-w64-tools/widl/Makefile.in
@@ -385,7 +385,7 @@ include/winnt.rh widl_CPPFLAGS = -I$(top_srcdir)/include -DINCLUDEDIR=\""@WIDL_INCLUDEDIR@"\" -DBIN_TO_INCLUDEDIR=\""@BIN_TO_INCLUDEDIR@"\" -DBIN_TO_DLLDIR=\""@BIN_TO_INCLUDEDIR@"\" -DDLLDIR="\"@prefix@/lib\"" -widl_CFLAGS = -O3 -g -Wall -Wformat -Wpacked -Wmissing-declarations -Wimplicit-function-declaration -Wmissing-prototypes -Wstrict-aliasing=2 +widl_CFLAGS = -O3 -g -Wall -Wformat -Wpacked -Wmissing-declarations -Wimplicit-function-declaration -Wmissing-prototypes DISTCHECK_CONFIGURE_FLAGS = --host=$(host) --target=$(target) all: all-am
diff --git a/mingw-w64-tools/widl/VERSION b/mingw-w64-tools/widl/VERSION index ecdc406..4075ee5 100644 --- a/mingw-w64-tools/widl/VERSION +++ b/mingw-w64-tools/widl/VERSION
@@ -1 +1 @@ -WIDL version 9.6 +WIDL version 9.8
diff --git a/mingw-w64-tools/widl/configure b/mingw-w64-tools/widl/configure index 7af3bca..f390d2f 100755 --- a/mingw-w64-tools/widl/configure +++ b/mingw-w64-tools/widl/configure
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for widl 9.6. +# Generated by GNU Autoconf 2.71 for widl 9.8. # # Report bugs to <mingw-w64-public@lists.sourceforge.net>. # @@ -610,8 +610,8 @@ # Identity of this package. PACKAGE_NAME='widl' PACKAGE_TARNAME='widl' -PACKAGE_VERSION='9.6' -PACKAGE_STRING='widl 9.6' +PACKAGE_VERSION='9.8' +PACKAGE_STRING='widl 9.8' PACKAGE_BUGREPORT='mingw-w64-public@lists.sourceforge.net' PACKAGE_URL='' @@ -1319,7 +1319,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures widl 9.6 to adapt to many kinds of systems. +\`configure' configures widl 9.8 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1391,7 +1391,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of widl 9.6:";; + short | recursive ) echo "Configuration of widl 9.8:";; esac cat <<\_ACEOF @@ -1493,7 +1493,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -widl configure 9.6 +widl configure 9.8 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1905,7 +1905,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by widl $as_me 9.6, which was +It was created by widl $as_me 9.8, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3295,7 +3295,7 @@ # Define the identity of the package. PACKAGE='widl' - VERSION='9.6' + VERSION='9.8' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -5789,7 +5789,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by widl $as_me 9.6, which was +This file was extended by widl $as_me 9.8, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5857,7 +5857,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -widl config.status 9.6 +widl config.status 9.8 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\"
diff --git a/mingw-w64-tools/widl/include/sal.h b/mingw-w64-tools/widl/include/sal.h index 72803a1..d49f630 100644 --- a/mingw-w64-tools/widl/include/sal.h +++ b/mingw-w64-tools/widl/include/sal.h
@@ -89,6 +89,7 @@ #define _Inout_ #define _Inout_bytecap_x_(count) #define _Inout_cap_(count) +#define _Inout_cap_c_(count) #define _Inout_opt_ #define _Inout_opt_cap_c_(count) #define _Inout_opt_z_
diff --git a/mingw-w64-tools/widl/include/winnt.h b/mingw-w64-tools/widl/include/winnt.h index 193f833..8299520 100644 --- a/mingw-w64-tools/widl/include/winnt.h +++ b/mingw-w64-tools/widl/include/winnt.h
@@ -1536,6 +1536,11 @@ #endif } CONTEXT_EX, *PCONTEXT_EX; +#define CONTEXT_EXCEPTION_ACTIVE 0x08000000 +#define CONTEXT_SERVICE_ACTIVE 0x10000000 +#define CONTEXT_EXCEPTION_REQUEST 0x40000000 +#define CONTEXT_EXCEPTION_REPORTING 0x80000000 + #define CONTEXT_ARM 0x0200000 #define CONTEXT_ARM_CONTROL (CONTEXT_ARM | 0x00000001) #define CONTEXT_ARM_INTEGER (CONTEXT_ARM | 0x00000002) @@ -6953,16 +6958,6 @@ } #endif -#if !defined(__i386__) || __has_builtin(_InterlockedDecrement64) -#pragma intrinsic(_InterlockedDecrement64) -__int64 _InterlockedDecrement64(__int64 volatile *); -#else -static FORCEINLINE __int64 InterlockedDecrement64( __int64 volatile *dest ) -{ - return InterlockedExchangeAdd64( dest, -1 ) - 1; -} -#endif - #if !defined(__i386__) || __has_builtin(_InterlockedExchangeAdd64) #pragma intrinsic(_InterlockedExchangeAdd64) __int64 _InterlockedExchangeAdd64(__int64 volatile *, __int64); @@ -6975,6 +6970,16 @@ } #endif +#if !defined(__i386__) || __has_builtin(_InterlockedDecrement64) +#pragma intrinsic(_InterlockedDecrement64) +__int64 _InterlockedDecrement64(__int64 volatile *); +#else +static FORCEINLINE __int64 InterlockedDecrement64( __int64 volatile *dest ) +{ + return InterlockedExchangeAdd64( dest, -1 ) - 1; +} +#endif + #if !defined(__i386__) || __has_builtin(_InterlockedIncrement64) #pragma intrinsic(_InterlockedIncrement64) __int64 _InterlockedIncrement64(__int64 volatile *);
diff --git a/mingw-w64-tools/widl/src/typegen.c b/mingw-w64-tools/widl/src/typegen.c index 063080b..9bfec7c 100644 --- a/mingw-w64-tools/widl/src/typegen.c +++ b/mingw-w64-tools/widl/src/typegen.c
@@ -420,7 +420,7 @@ static unsigned int get_stack_size( const var_t *var, unsigned int *stack_align, int *by_value ) { unsigned int stack_size, align = 0; - int by_val; + int by_val = 0; switch (typegen_detect_type( var->declspec.type, var->attrs, TDT_ALL_TYPES )) { @@ -449,6 +449,7 @@ switch (target.cpu) { case CPU_x86_64: + case CPU_ARM64EC: by_val = (stack_size == 1 || stack_size == 2 || stack_size == 4 || stack_size == 8); break; case CPU_ARM64: @@ -457,14 +458,13 @@ case CPU_ARM: by_val = 1; break; - default: + case CPU_i386: align = pointer_size; by_val = 1; break; } break; default: - by_val = 0; break; } if (align < pointer_size) align = pointer_size; @@ -1372,6 +1372,129 @@ return interpreted_mode; } +/* replace consecutive params code by a repeat sequence: 0x9d code<1> repeat_count<2> */ +static unsigned int compress_params_array( unsigned char *params, unsigned int count ) +{ + unsigned int i, j; + + for (i = 0; i + 4 <= count; i++) + { + for (j = 1; i + j < count; j++) if (params[i + j] != params[i]) break; + if (j < 4) continue; + params[i] = 0x9d; + params[i + 2] = j & 0xff; + params[i + 3] = j >> 8; + memmove( params + i + 4, params + i + j, count - (i + j) ); + count -= j - 4; + i += 3; + } + return count; +} + +/* fill the parameters array for the procedure extra data on ARM platforms */ +static unsigned int fill_params_array( const type_t *iface, const var_t *func, + unsigned char *params, unsigned int count ) +{ + unsigned int reg_count = 0, float_count = 0, double_count = 0, stack_pos = 0, offset = 0; + var_list_t *args = type_function_get_args( func->declspec.type ); + enum type_basic_type type; + unsigned int size, pos, align; + var_t *var; + + memset( params, 0x9f /* padding */, count ); + + if (is_object( iface )) + { + params[0] = 0x80 + reg_count++; + offset += pointer_size; + } + + if (args) LIST_FOR_EACH_ENTRY( var, args, var_t, entry ) + { + type = TYPE_BASIC_LONG; + if (type_get_type( var->declspec.type ) == TYPE_BASIC) + type = type_basic_get_type( var->declspec.type ); + + size = get_stack_size( var, &align, NULL ); + offset = ROUND_SIZE( offset, align ); + pos = offset / pointer_size; + + if (target.cpu == CPU_ARM64) + { + switch (type) + { + case TYPE_BASIC_FLOAT: + case TYPE_BASIC_DOUBLE: + if (double_count >= 8) break; + params[pos] = 0x88 + double_count++; + offset += size; + continue; + + default: + reg_count = ROUND_SIZE( reg_count, align / pointer_size ); + if (reg_count > 8 - size / pointer_size) break; + while (size) + { + params[pos++] = 0x80 + reg_count++; + offset += pointer_size; + size -= pointer_size; + } + continue; + } + } + else /* CPU_ARM */ + { + switch (type) + { + case TYPE_BASIC_FLOAT: + if (!(float_count % 2)) float_count = max( float_count, double_count * 2 ); + if (float_count >= 16) + { + stack_pos = ROUND_SIZE( stack_pos, align ); + params[pos] = 0x100 - (offset - stack_pos) / pointer_size; + stack_pos += size; + } + else + { + params[pos] = 0x84 + float_count++; + } + offset += size; + continue; + + case TYPE_BASIC_DOUBLE: + double_count = max( double_count, (float_count + 1) / 2 ); + if (double_count >= 8) break; + params[pos] = 0x84 + 2 * double_count; + params[pos + 1] = 0x84 + 2 * double_count + 1; + double_count++; + offset += size; + continue; + + default: + reg_count = ROUND_SIZE( reg_count, align / pointer_size ); + if (reg_count <= 4 - size / pointer_size || !stack_pos) + { + while (size && reg_count < 4) + { + params[pos++] = 0x80 + reg_count++; + offset += pointer_size; + size -= pointer_size; + } + } + break; + } + } + + stack_pos = ROUND_SIZE( stack_pos, align ); + memset( params + pos, 0x100 - (offset - stack_pos) / pointer_size, size / pointer_size ); + stack_pos += size; + offset += size; + } + + while (count && params[count - 1] == 0x9f) count--; + return count; +} + static void write_proc_func_interp( FILE *file, int indent, const type_t *iface, const var_t *func, unsigned int *offset, unsigned short num_proc ) @@ -1390,6 +1513,7 @@ unsigned int stack_size = 0; unsigned int stack_offset = 0; unsigned int stack_align; + unsigned int extra_size = 0; unsigned short param_num = 0; unsigned short handle_stack_offset = 0; unsigned short handle_param_num = 0; @@ -1477,16 +1601,22 @@ print_file( file, indent, "NdrFcShort(0x%x),\t/* server buffer = %u */\n", size, size ); print_file( file, indent, "0x%02x,\n", oi2_flags ); print_file( file, indent, "0x%02x,\t/* %u params */\n", nb_args, nb_args ); - print_file( file, indent, "0x%02x,\n", pointer_size == 8 ? 10 : 8 ); - print_file( file, indent, "0x%02x,\n", ext_flags ); - print_file( file, indent, "NdrFcShort(0x0),\n" ); /* server corr hint */ - print_file( file, indent, "NdrFcShort(0x0),\n" ); /* client corr hint */ - print_file( file, indent, "NdrFcShort(0x0),\n" ); /* FIXME: notify index */ - *offset += 14; - if (pointer_size == 8) + *offset += 6; + extra_size = 8; + + switch (target.cpu) + { + case CPU_x86_64: + case CPU_ARM64EC: { unsigned short pos = 0, fpu_mask = 0; + extra_size += 2; + print_file( file, indent, "0x%02x,\n", extra_size ); + print_file( file, indent, "0x%02x,\n", ext_flags ); + print_file( file, indent, "NdrFcShort(0x0),\n" ); /* server corr hint */ + print_file( file, indent, "NdrFcShort(0x0),\n" ); /* client corr hint */ + print_file( file, indent, "NdrFcShort(0x0),\n" ); /* FIXME: notify index */ if (is_object( iface )) pos += 2; if (args) LIST_FOR_EACH_ENTRY( var, args, var_t, entry ) { @@ -1503,8 +1633,39 @@ if (pos >= 16) break; } print_file( file, indent, "NdrFcShort(0x%x),\n", fpu_mask ); /* floating point mask */ - *offset += 2; + break; } + case CPU_ARM: + case CPU_ARM64: + { + unsigned int i, len, count = stack_size / pointer_size; + unsigned char *params = xmalloc( count ); + + count = fill_params_array( iface, func, params, count ); + len = compress_params_array( params, count ); + + extra_size += 3 + len + !(len % 2); + print_file( file, indent, "0x%02x,\n", extra_size ); + print_file( file, indent, "0x%02x,\n", ext_flags ); + print_file( file, indent, "NdrFcShort(0x0),\n" ); /* server corr hint */ + print_file( file, indent, "NdrFcShort(0x0),\n" ); /* client corr hint */ + print_file( file, indent, "NdrFcShort(0x0),\n" ); /* FIXME: notify index */ + print_file( file, indent, "NdrFcShort(0x%02x),\n", count ); + print_file( file, indent, "0x%02x,\n", len ); + for (i = 0; i < len; i++) print_file( file, indent, "0x%02x,\n", params[i] ); + if (!(len % 2)) print_file( file, indent, "0x00,\n" ); + free( params ); + break; + } + case CPU_i386: + print_file( file, indent, "0x%02x,\n", extra_size ); + print_file( file, indent, "0x%02x,\n", ext_flags ); + print_file( file, indent, "NdrFcShort(0x0),\n" ); /* server corr hint */ + print_file( file, indent, "NdrFcShort(0x0),\n" ); /* client corr hint */ + print_file( file, indent, "NdrFcShort(0x0),\n" ); /* FIXME: notify index */ + break; + } + *offset += extra_size; /* emit argument data */ if (args) LIST_FOR_EACH_ENTRY( var, args, var_t, entry ) @@ -1826,6 +1987,7 @@ break; } offset += size; + if (offset > baseoff) robust_flags &= ~RobustEarly; } } @@ -2456,7 +2618,7 @@ if (type_get_type(type) == TYPE_UNION && is_attr(attrs, ATTR_SWITCHIS)) { absoff = *corroff; - *corroff += 8; + *corroff += interpreted_mode ? 10 : 8; } else { @@ -2546,7 +2708,7 @@ if (!fc) fc = FC_LONG; if (is_attr(ft->attrs, ATTR_SWITCHTYPE)) - absoff += 8; /* we already have a corr descr, skip it */ + absoff += interpreted_mode ? 10 : 8; /* we already have a corr descr, skip it */ print_file(file, 0, "/* %d */\n", *tfsoff); print_file(file, 2, "0x%x,\t/* FC_NON_ENCAPSULATED_UNION */\n", FC_NON_ENCAPSULATED_UNION); print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
diff --git a/mingw-w64-tools/widl/src/widl.c b/mingw-w64-tools/widl/src/widl.c index 30bff0f..a03abe0 100644 --- a/mingw-w64-tools/widl/src/widl.c +++ b/mingw-w64-tools/widl/src/widl.c
@@ -110,7 +110,7 @@ int old_names = 0; int old_typelib = 0; int winrt_mode = 0; -int interpreted_mode = 0; +int interpreted_mode = 1; int use_abi_namespace = 0; static int stdinc = 1;
diff --git a/mingw-w64-tools/widl/src/write_msft.c b/mingw-w64-tools/widl/src/write_msft.c index 31e340e..b9a3d66 100644 --- a/mingw-w64-tools/widl/src/write_msft.c +++ b/mingw-w64-tools/widl/src/write_msft.c
@@ -2757,7 +2757,6 @@ const statement_t *stmt; const attr_t *attr; time_t cur_time; - char *time_override; unsigned int version = 7 << 24 | 555; /* 7.00.0555 */ static const struct uuid midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; static const struct uuid midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; @@ -2813,11 +2812,13 @@ } } - /* midl adds two sets of custom data to the library: the current unix time - and midl's version number */ - time_override = getenv( "WIDL_TIME_OVERRIDE"); - cur_time = time_override ? atol( time_override) : time(NULL); - sprintf(info_string, "Created by WIDL version %s at %s", PACKAGE_VERSION, ctime(&cur_time)); + /* midl adds three sets of custom data to the library: + * - 2147483647 (INT_MAX, previously the current Unix time) + * - midl's version number + * - a string representation of those + */ + cur_time = 2147483647; + sprintf(info_string, "Created by WIDL version %s at %s", PACKAGE_VERSION, asctime(gmtime(&cur_time))); set_custdata(msft, &midl_info_guid, VT_BSTR, info_string, &msft->typelib_header.CustomDataOffset); set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset); set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset);
diff --git a/mingw-w64-tools/widl/src/write_sltg.c b/mingw-w64-tools/widl/src/write_sltg.c index 94ebf67..d09fdb3 100644 --- a/mingw-w64-tools/widl/src/write_sltg.c +++ b/mingw-w64-tools/widl/src/write_sltg.c
@@ -354,28 +354,37 @@ } } -static void add_block(struct sltg_typelib *sltg, void *data, int length, const char *name) +static void add_block_index(struct sltg_typelib *sltg, void *data, int length, int index) { - chat("add_block: %p,%d,\"%s\"\n", data, length, name); - sltg->blocks = xrealloc(sltg->blocks, sizeof(sltg->blocks[0]) * (sltg->block_count + 1)); sltg->blocks[sltg->block_count].length = length; sltg->blocks[sltg->block_count].data = data; - sltg->blocks[sltg->block_count].index_string = add_index(&sltg->index, name); + sltg->blocks[sltg->block_count].index_string = index; sltg->block_count++; } -static void add_library_block(struct sltg_typelib *typelib) +static void add_block(struct sltg_typelib *sltg, void *data, int size, const char *name) +{ + struct sltg_block *block = xmalloc(sizeof(*block)); + int index; + + chat("add_block: %p,%d,\"%s\"\n", data, size, name); + + index = add_index(&sltg->index, name); + + add_block_index(sltg, data, size, index); +} + +static void *create_library_block(struct sltg_typelib *typelib, int *size, int *index) { void *block; short *p; - int size; - size = sizeof(short) * 9 + sizeof(int) * 3 + sizeof(GUID); - if (typelib->library.helpstring) size += strlen(typelib->library.helpstring); - if (typelib->library.helpfile) size += strlen(typelib->library.helpfile); + *size = sizeof(short) * 9 + sizeof(int) * 3 + sizeof(GUID); + if (typelib->library.helpstring) *size += strlen(typelib->library.helpstring); + if (typelib->library.helpfile) *size += strlen(typelib->library.helpfile); - block = xmalloc(size); + block = xmalloc(*size); p = block; *p++ = 0x51cc; /* magic */ *p++ = 3; /* res02 */ @@ -408,7 +417,9 @@ p += 2; *(GUID *)p = typelib->library.uuid; - add_block(typelib, block, size, "dir"); + *index = add_index(&typelib->index, "dir"); + + return block; } static const char *new_index_name(void) @@ -685,8 +696,8 @@ return href << 2; } -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) +static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data, type_t *type, short param_flags, + short flags, short base_offset, int *size_instance, struct sltg_hrefmap *hrefmap) { short vt, vt_flags, desc_offset; @@ -756,7 +767,6 @@ size_instance = NULL; /* don't account for element size */ } - append_data(data, array, size); desc_offset = data->size; @@ -779,19 +789,19 @@ if (is_ptr(ref)) { - chat("write_var_desc: vt VT_PTR | 0x0400\n"); - vt = VT_PTR | 0x0400; + chat("write_var_desc: vt VT_PTR | 0x0400 | %04x\n", param_flags); + vt = VT_PTR | 0x0400 | param_flags; append_data(data, &vt, sizeof(vt)); - write_var_desc(typelib, data, ref, 0, base_offset, size_instance, hrefmap); + write_var_desc(typelib, data, ref, 0, 0, base_offset, size_instance, hrefmap); } else - write_var_desc(typelib, data, ref, 0x0e00, base_offset, size_instance, hrefmap); + write_var_desc(typelib, data, ref, param_flags, 0x0e00, base_offset, size_instance, hrefmap); return desc_offset; } chat("write_var_desc: vt %d, flags %04x\n", vt, flags); - vt_flags = vt | flags; + vt_flags = vt | flags | param_flags; append_data(data, &vt_flags, sizeof(vt_flags)); if (vt == VT_USERDEFINED) @@ -917,7 +927,8 @@ init_sltg_data(&var_data[i]); base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable); - type_desc_offset[i] = write_var_desc(typelib, &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, 0, + base_offset, &size_instance, &hrefmap); dump_var_desc(var_data[i].data, var_data[i].size); if (var_data[i].size > sizeof(short)) @@ -1020,11 +1031,9 @@ 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; @@ -1101,24 +1110,65 @@ return flags; } +static int get_param_flags(const var_t *param) +{ + const attr_t *attr; + int flags, in, out; + + if (!param->attrs) return 0; + + flags = 0; + in = out = 0; + + LIST_FOR_EACH_ENTRY(attr, param->attrs, const attr_t, entry) + { + switch(attr->type) + { + case ATTR_IN: + in++; + break; + case ATTR_OUT: + out++; + break; + case ATTR_PARAMLCID: + flags |= 0x2000; + break; + case ATTR_RETVAL: + flags |= 0x80; + break; + default: + chat("unhandled param attr %d\n", attr->type); + break; + } + } + + if (out) + flags |= in ? 0x8000 : 0x4000; + else if (!in) + flags |= 0xc000; + + 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) + int idx, int dispid, 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; + int funcflags = 0, 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); + chat("add_func_desc: %s, idx %#x, dispid %#x\n", func->name, idx, dispid); 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); + 0, 0, base_offset, NULL, hrefmap); dump_var_desc(ret_data.data, ret_data.size); arg_data_size = 0; @@ -1144,13 +1194,16 @@ LIST_FOR_EACH_ENTRY(arg, type_function_get_args(func->declspec.type), const var_t, entry) { const attr_t *attr; + short param_flags = get_param_flags(arg); 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); + + arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->declspec.type, param_flags, 0, + arg_offset, NULL, hrefmap); dump_var_desc(arg_data[i].data, arg_data[i].size); if (arg_data[i].size > sizeof(short)) @@ -1231,7 +1284,6 @@ short name, type_offset; name = base_offset != -1 ? add_name(&typelib->name_table, arg->name) : -1; - append_data(data, &name, sizeof(name)); if (arg_data[i].size > sizeof(short)) { @@ -1239,8 +1291,12 @@ arg_offset += arg_data[i].size; } else + { + name |= 1; type_offset = *(short *)arg_data[i].data; + } + append_data(data, &name, sizeof(name)); append_data(data, &type_offset, sizeof(type_offset)); if (base_offset != -1) @@ -1293,6 +1349,7 @@ struct sltg_tail tail; int member_offset, base_offset, func_data_size, i; int func_count, inherited_func_count = 0; + int dispid, inherit_level = 0; if (iface->typelib_idx != -1) return; @@ -1333,6 +1390,7 @@ while (inherit) { + inherit_level++; inherited_func_count += list_count(type_iface_get_stmts(inherit)); inherit = type_iface_get_inherit(inherit); } @@ -1348,7 +1406,7 @@ STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) { - add_func_desc(typelib, &data, stmt_func->u.var, -1, -1, &hrefmap); + add_func_desc(typelib, &data, stmt_func->u.var, -1, -1, -1, &hrefmap); } func_data_size = data.size; @@ -1383,13 +1441,16 @@ write_impl_href(&data, inherit_href); i = 0; + dispid = 0x60000000 | (inherit_level << 16); STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) { - if (i == func_count - 1) i |= 0x80000000; + int idx = inherited_func_count + i; + + if (i == func_count - 1) idx |= 0x80000000; base_offset += add_func_desc(typelib, &data, stmt_func->u.var, - inherited_func_count + i, base_offset, &hrefmap); + idx, dispid + i, base_offset, &hrefmap); i++; } @@ -1556,8 +1617,10 @@ /* library block length includes helpstrings and name table */ entry.length = sltg->blocks[sltg->block_count - 1].length + 0x40 /* pad after library block */ + - sizeof(sltg->typeinfo_count) + sltg->typeinfo_size + 4 /* library block offset */ + 6 /* dummy help strings */ + - 12 /* name table header */ + 0x200 /* name table hash */ + sltg->name_table.size; + sizeof(sltg->typeinfo_count) + sltg->typeinfo_size + 4 /* library block size */ + 6 /* dummy help strings */ + + 12 /* name table header */ + 0x200 /* name table hash */ + + sizeof(sltg->name_table.size) + sltg->name_table.size + + 4 /* 0x01ffff01 */ + 4 /* 0 */; entry.index_string = sltg->blocks[sltg->block_count - 1].index_string; entry.next = 0; chat("sltg_write_header: writing library block entry %d: length %#x, index_string %#x, next %#x\n", @@ -1684,6 +1747,8 @@ { struct sltg_typelib sltg; const statement_t *stmt; + void *library_block; + int library_block_size, library_block_index; if (pointer_size != 4) error("Only 32-bit platform is supported\n"); @@ -1700,12 +1765,14 @@ init_name_table(&sltg.name_table); init_library(&sltg); - add_library_block(&sltg); + library_block = create_library_block(&sltg, &library_block_size, &library_block_index); if (typelib->stmts) LIST_FOR_EACH_ENTRY(stmt, typelib->stmts, const statement_t, entry) add_statement(&sltg, stmt); + add_block_index(&sltg, library_block, library_block_size, library_block_index); + save_all_changes(&sltg); return 1;