oleaut32: Dynamic invocation for x86

Juan Lang juan.lang at gmail.com
Thu Aug 20 17:09:19 CDT 2009


Hi, I'm sending this on behalf of Jon Griffiths, who says he didn't
get comment on it before.  I'm seeking comment on it now.

It fixes bug 10050, which reports several related apps that use
ITypeInfo::Invoke.  The one tested, ZFlash, calls Invoke with 70
arguments.

Bug 11447 reports a similar problem with the Excel 2003 Solver add-in.
 It calls ITypeInfo::Invoke with 126 arguments.

Personally, I don't think the cut-and-paste approach we've been taking
to fix this works all that well for a 126-argument function, so it
seems like an assembly approach is the only tenable method.  I'm not
certain whether Jon's approach is the correct one, but since it didn't
get any comment before, I'd like to know:  if it isn't acceptable, why
not?

Thanks,
--Juan
-------------- next part --------------
From b459cf64b57c7c06e5d840ae61f5d02f07717dee Mon Sep 17 00:00:00 2001
From: Jon Griffiths <jon_p_griffiths at yahoo.com>
Date: Thu, 20 Aug 2009 14:02:47 -0700
Subject: [PATCH] Dynamic invocation for x86

---
 dlls/oleaut32/typelib.c |   40 +++++++++++++++++++++++++++++++++++++++-
 1 files changed, 39 insertions(+), 1 deletions(-)

diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index f16b459..4187e42 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -5597,6 +5597,36 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
     return DISP_E_UNKNOWNNAME;
 }
 
+#ifdef __i386__
+/* Dynamically push arguments and call a function */
+#define DEFINE_INVOKE_WRAPPER(name, pop_size) \
+extern DWORD name(void *func, int nrargs, DWORD *args); \
+__ASM_GLOBAL_FUNC(name, \
+                  "pushl %ebp\n\t" \
+                  "movl  %esp, %ebp\n\t" \
+                  "movl  12(%ebp), %eax\n\t" \
+                  "movl  16(%ebp), %ecx\n\t" \
+                  "shll  $2, %eax\n\t" \
+                  "subl  %eax, %esp\n\t" \
+                  "subl  $4, %eax\n\t" \
+                  "js    1f\n\t" \
+                  "0:\n\t" \
+                  "pushl (%ecx, %eax)\n\t" \
+                  "subl  $4, %eax\n\t" \
+                  "jns   0b\n\t" \
+                  "1:\n\t" \
+                  "movl  8(%ebp), %eax\n\t" \
+                  "call  *%eax\n\t" \
+                  "movl  12(%ebp), %ecx\n\t" \
+                  "leal  (%esp, %ecx, " #pop_size "), %esp\n\t" \
+                  "popl  %ebp\n\t" \
+                  "ret\n\t" )
+
+DEFINE_INVOKE_WRAPPER(invoke_stdcall, 4);
+DEFINE_INVOKE_WRAPPER(invoke_cdecl, 8);
+
+#endif /* __i386__ */
+
 /* ITypeInfo::Invoke
  *
  * Invokes a method, or accesses a property of an object, that implements the
@@ -5614,8 +5644,15 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) {
     }
 
     switch (callconv) {
+#ifdef __i386__
+    case CC_STDCALL:
+        res = invoke_stdcall(func, nrargs, args);
+        break;
+    case CC_CDECL:
+        res = invoke_cdecl(func, nrargs, args);
+        break;
+#else
     case CC_STDCALL:
-
 	switch (nrargs) {
 	case 0:
 		res = func();
@@ -5716,6 +5753,7 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) {
 		break;
 	}
 	break;
+#endif /* __i386__ */
     default:
 	FIXME("unsupported calling convention %d\n",callconv);
 	res = -1;
-- 
1.6.3.2


More information about the wine-patches mailing list