summaryrefslogtreecommitdiffstats
path: root/xpcom/reflect/xptcall/md/win32
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/reflect/xptcall/md/win32')
-rw-r--r--xpcom/reflect/xptcall/md/win32/moz.build45
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcinvoke.cpp45
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64.asm107
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64_gnu.s110
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_msvc.asm63
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_64.cpp59
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_gnu.cpp106
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcstubs.cpp227
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcstubs_asm_x86_64.asm335
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64.cpp197
-rw-r--r--xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64_gnu.cpp297
11 files changed, 1591 insertions, 0 deletions
diff --git a/xpcom/reflect/xptcall/md/win32/moz.build b/xpcom/reflect/xptcall/md/win32/moz.build
new file mode 100644
index 000000000..5dbe41d76
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/moz.build
@@ -0,0 +1,45 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+if CONFIG['TARGET_CPU'] == 'x86_64':
+ if CONFIG['GNU_CXX']:
+ SOURCES += [
+ 'xptcinvoke_x86_64.cpp',
+ 'xptcstubs_x86_64_gnu.cpp',
+ ]
+ SOURCES += [
+ 'xptcinvoke_asm_x86_64_gnu.s'
+ ]
+ else:
+ SOURCES += [
+ 'xptcinvoke_x86_64.cpp',
+ 'xptcstubs_x86_64.cpp'
+ ]
+ SOURCES += [
+ 'xptcinvoke_asm_x86_64.asm',
+ 'xptcstubs_asm_x86_64.asm'
+ ]
+else:
+ if CONFIG['GNU_CXX']:
+ SOURCES += [
+ 'xptcinvoke_x86_gnu.cpp',
+ 'xptcstubs.cpp',
+ ]
+ else:
+ SOURCES += [
+ 'xptcinvoke.cpp',
+ 'xptcinvoke_asm_x86_msvc.asm',
+ 'xptcstubs.cpp',
+ ]
+ SOURCES['xptcinvoke.cpp'].no_pgo = True
+ SOURCES['xptcinvoke_asm_x86_msvc.asm'].flags += ['-safeseh']
+
+FINAL_LIBRARY = 'xul'
+
+LOCAL_INCLUDES += [
+ '../..',
+ '/xpcom/reflect/xptinfo',
+]
diff --git a/xpcom/reflect/xptcall/md/win32/xptcinvoke.cpp b/xpcom/reflect/xptcall/md/win32/xptcinvoke.cpp
new file mode 100644
index 000000000..faec869f6
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcinvoke.cpp
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Platform specific code to invoke XPCOM methods on native objects */
+
+#include "xptcprivate.h"
+
+#ifndef WIN32
+#error "This code is for Win32 only"
+#endif
+
+extern "C" void __fastcall
+invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, nsXPTCVariant* s)
+{
+ for(; paramCount > 0; paramCount--, d++, s++)
+ {
+ if(s->IsPtrData())
+ {
+ *((void**)d) = s->ptr;
+ continue;
+ }
+ switch(s->type)
+ {
+ case nsXPTType::T_I8 : *((int8_t*) d) = s->val.i8; break;
+ case nsXPTType::T_I16 : *((int16_t*) d) = s->val.i16; break;
+ case nsXPTType::T_I32 : *((int32_t*) d) = s->val.i32; break;
+ case nsXPTType::T_I64 : *((int64_t*) d) = s->val.i64; d++; break;
+ case nsXPTType::T_U8 : *((uint8_t*) d) = s->val.u8; break;
+ case nsXPTType::T_U16 : *((uint16_t*)d) = s->val.u16; break;
+ case nsXPTType::T_U32 : *((uint32_t*)d) = s->val.u32; break;
+ case nsXPTType::T_U64 : *((uint64_t*)d) = s->val.u64; d++; break;
+ case nsXPTType::T_FLOAT : *((float*) d) = s->val.f; break;
+ case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; break;
+ case nsXPTType::T_BOOL : *((bool*) d) = s->val.b; break;
+ case nsXPTType::T_CHAR : *((char*) d) = s->val.c; break;
+ case nsXPTType::T_WCHAR : *((wchar_t*) d) = s->val.wc; break;
+ default:
+ // all the others are plain pointer types
+ *((void**)d) = s->val.p;
+ break;
+ }
+ }
+}
diff --git a/xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64.asm b/xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64.asm
new file mode 100644
index 000000000..bf7c2ef0c
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64.asm
@@ -0,0 +1,107 @@
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+extrn invoke_copy_to_stack:PROC
+
+
+.CODE
+
+;
+;XPTC__InvokebyIndex(nsISupports* that, uint32_t methodIndex,
+; uint32_t paramCount, nsXPTCVariant* params)
+;
+
+XPTC__InvokebyIndex PROC FRAME
+
+ ; store register parameters
+
+ mov qword ptr [rsp+32], r9 ; params
+ mov dword ptr [rsp+24], r8d ; paramCount
+ mov dword ptr [rsp+16], edx ; methodIndex
+ mov qword ptr [rsp+8], rcx ; that
+
+ push rbp
+ .PUSHREG rbp
+ mov rbp, rsp ; store current RSP to RBP
+ .SETFRAME rbp, 0
+ .ENDPROLOG
+
+ sub rsp, 32
+
+ ; maybe we don't have any parameters to copy
+
+ test r8d, r8d
+ jz noparams
+
+ ;
+ ; Build stack for stdcall
+ ;
+
+ ; 1st parameter is space for parameters
+
+ mov eax, r8d
+ or eax, 1
+ shl rax, 3 ; *= 8
+ sub rsp, rax
+ mov rcx, rsp
+
+ ; 2nd parameter is parameter count
+
+ mov edx, r8d
+
+ ; 3rd parameter is params
+
+ mov r8, r9
+
+ sub rsp, 40
+ call invoke_copy_to_stack ; rcx = d
+ ; edx = paramCount
+ ; r8 = s
+ add rsp, 32
+
+ ; Current stack is the following.
+ ;
+ ; 0h: [space (for this)]
+ ; 8h: [1st parameter]
+ ; 10h: [2nd parameter]
+ ; 18h: [3rd parameter]
+ ; 20h: [4th parameter]
+ ; ...
+ ;
+ ; On Win64 ABI, the first 4 parameters are passed using registers,
+ ; and others are on stack.
+
+ ; 1st, 2nd and 3rd arguments are passed via registers
+
+ mov rdx, qword ptr [rsp+8] ; 1st parameter
+ movsd xmm1, qword ptr [rsp+8] ; for double
+
+ mov r8, qword ptr [rsp+16] ; 2nd parameter
+ movsd xmm2, qword ptr [rsp+16] ; for double
+
+ mov r9, qword ptr [rsp+24] ; 3rd parameter
+ movsd xmm3, qword ptr [rsp+24] ; for double
+
+ ; rcx register is this
+
+ mov rcx, qword ptr [rbp+8+8] ; that
+
+noparams:
+
+ ; calculate call address
+
+ mov r11, qword ptr [rcx]
+ mov eax, dword ptr [rbp+16+8] ; methodIndex
+
+ call qword ptr [r11+rax*8] ; stdcall, i.e. callee cleans up stack.
+
+ mov rsp, rbp
+ pop rbp
+
+ ret
+
+XPTC__InvokebyIndex ENDP
+
+
+END
diff --git a/xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64_gnu.s b/xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64_gnu.s
new file mode 100644
index 000000000..006e0444b
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64_gnu.s
@@ -0,0 +1,110 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+.extern invoke_copy_to_stack
+
+
+.text
+.intel_syntax noprefix
+
+#
+#_XPTC__InvokebyIndex(nsISupports* that, uint32_t methodIndex,
+# uint32_t paramCount, nsXPTCVariant* params)
+#
+
+.globl XPTC__InvokebyIndex
+.def XPTC__InvokebyIndex
+ .scl 3
+ .type 46
+.endef
+XPTC__InvokebyIndex:
+
+ # store register parameters
+
+ mov qword ptr [rsp+32], r9 # params
+ mov dword ptr [rsp+24], r8d # paramCount
+ mov dword ptr [rsp+16], edx # methodIndex
+ mov qword ptr [rsp+8], rcx # that
+
+ push rbp
+ # .PUSHREG rbp
+ mov rbp, rsp # store current RSP to RBP
+ # .SETFRAME rbp, 0
+ # .ENDPROLOG
+
+ sub rsp, 32
+
+ # maybe we don't have any parameters to copy
+
+ test r8d, r8d
+ jz noparams
+
+ #
+ # Build stack for stdcall
+ #
+
+ # 1st parameter is space for parameters
+
+ mov eax, r8d
+ or eax, 1
+ shl rax, 3 # *= 8
+ sub rsp, rax
+ mov rcx, rsp
+
+ # 2nd parameter is parameter count
+
+ mov edx, r8d
+
+ # 3rd parameter is params
+
+ mov r8, r9
+
+ sub rsp, 40
+ call invoke_copy_to_stack # rcx = d
+ # edx = paramCount
+ # r8 = s
+ add rsp, 32
+
+ # Current stack is the following.
+ #
+ # 0h: [space (for this)]
+ # 8h: [1st parameter]
+ # 10h: [2nd parameter]
+ # 18h: [3rd parameter]
+ # 20h: [4th parameter]
+ # ...
+ #
+ # On Win64 ABI, the first 4 parameters are passed using registers,
+ # and others are on stack.
+
+ # 1st, 2nd and 3rd arguments are passed via registers
+
+ mov rdx, qword ptr [rsp+8] # 1st parameter
+ movsd xmm1, qword ptr [rsp+8] # for double
+
+ mov r8, qword ptr [rsp+16] # 2nd parameter
+ movsd xmm2, qword ptr [rsp+16] # for double
+
+ mov r9, qword ptr [rsp+24] # 3rd parameter
+ movsd xmm3, qword ptr [rsp+24] # for double
+
+ # rcx register is this
+
+ mov rcx, qword ptr [rbp+8+8] # that
+
+noparams:
+
+ # calculate call address
+
+ mov r11, qword ptr [rcx]
+ mov eax, dword ptr [rbp+16+8] # methodIndex
+
+ call qword ptr [r11+rax*8] # stdcall, i.e. callee cleans up stack.
+
+ mov rsp, rbp
+ pop rbp
+
+ ret
+
+
diff --git a/xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_msvc.asm b/xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_msvc.asm
new file mode 100644
index 000000000..f3b7a1826
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_msvc.asm
@@ -0,0 +1,63 @@
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+ TITLE xptcinvoke_asm_x86_msvc.asm
+ .686P
+ .model flat
+
+PUBLIC _NS_InvokeByIndex
+EXTRN @invoke_copy_to_stack@12:PROC
+
+;
+; extern "C" nsresult __cdecl
+; NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
+; uint32_t paramCount, nsXPTCVariant* params)
+;
+
+_TEXT SEGMENT
+_NS_InvokeByIndex PROC
+
+ ; Build frame
+ push ebp
+ mov ebp, esp
+
+ ; Save paramCount for later
+ mov edx, dword ptr [ebp+16]
+
+ ; Do we have any parameters?
+ test edx, edx
+ jz noparams
+
+ ; Build call for copy_to_stack, which is __fastcall
+
+ ; Allocate space for parameters. 8 is the biggest size
+ ; any parameter can be, so assume that all our parameters
+ ; are that large.
+ mov eax, edx
+ shl eax, 3
+ sub esp, eax
+
+ mov ecx, esp
+ push dword ptr [ebp+20]
+ call @invoke_copy_to_stack@12
+noparams:
+ ; Push the `this' parameter for the call.
+ mov ecx, dword ptr [ebp+8]
+ push ecx
+
+ ; Load the vtable.
+ mov edx, dword ptr [ecx]
+
+ ; Call the vtable index at `methodIndex'.
+ mov eax, dword ptr [ebp+12]
+ call dword ptr [edx+eax*4]
+
+ ; Reset and return.
+ mov esp, ebp
+ pop ebp
+ ret
+_NS_InvokeByIndex ENDP
+_TEXT ENDS
+
+END
diff --git a/xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_64.cpp b/xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_64.cpp
new file mode 100644
index 000000000..36b454b35
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_64.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Platform specific code to invoke XPCOM methods on native objects */
+
+#include "xptcprivate.h"
+
+extern "C" void
+invoke_copy_to_stack(uint64_t* d, uint32_t paramCount, nsXPTCVariant* s)
+{
+ for(; paramCount > 0; paramCount--, d++, s++)
+ {
+ if(s->IsPtrData())
+ {
+ *((void**)d) = s->ptr;
+ continue;
+ }
+
+ /*
+ * AMD64 platform uses 8 bytes align.
+ */
+
+ switch(s->type)
+ {
+ case nsXPTType::T_I8 : *((int8_t*) d) = s->val.i8; break;
+ case nsXPTType::T_I16 : *((int16_t*) d) = s->val.i16; break;
+ case nsXPTType::T_I32 : *((int32_t*) d) = s->val.i32; break;
+ case nsXPTType::T_I64 : *((int64_t*) d) = s->val.i64; break;
+ case nsXPTType::T_U8 : *((uint8_t*) d) = s->val.u8; break;
+ case nsXPTType::T_U16 : *((uint16_t*)d) = s->val.u16; break;
+ case nsXPTType::T_U32 : *((uint32_t*)d) = s->val.u32; break;
+ case nsXPTType::T_U64 : *((uint64_t*)d) = s->val.u64; break;
+ case nsXPTType::T_FLOAT : *((float*) d) = s->val.f; break;
+ case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; break;
+ case nsXPTType::T_BOOL : *((bool*) d) = s->val.b; break;
+ case nsXPTType::T_CHAR : *((char*) d) = s->val.c; break;
+ case nsXPTType::T_WCHAR : *((wchar_t*) d) = s->val.wc; break;
+ default:
+ // all the others are plain pointer types
+ *((void**)d) = s->val.p;
+ break;
+ }
+ }
+}
+
+extern "C" nsresult
+XPTC__InvokebyIndex(nsISupports* that, uint32_t methodIndex,
+ uint32_t paramCount, nsXPTCVariant* params);
+
+extern "C"
+EXPORT_XPCOM_API(nsresult)
+NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
+ uint32_t paramCount, nsXPTCVariant* params)
+{
+ return XPTC__InvokebyIndex(that, methodIndex, paramCount, params);
+}
+
diff --git a/xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_gnu.cpp b/xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_gnu.cpp
new file mode 100644
index 000000000..0e73e99f3
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_gnu.cpp
@@ -0,0 +1,106 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Platform specific code to invoke XPCOM methods on native objects */
+
+#include "xptcprivate.h"
+
+extern "C" {
+void __attribute__ ((__used__)) __attribute__ ((regparm(3)))
+invoke_copy_to_stack(uint32_t paramCount, nsXPTCVariant* s, uint32_t* d)
+{
+ for(uint32_t i = paramCount; i >0; i--, d++, s++)
+ {
+ if(s->IsPtrData())
+ {
+ *((void**)d) = s->ptr;
+ continue;
+ }
+
+ switch(s->type)
+ {
+ case nsXPTType::T_I8 : *((int8_t*) d) = s->val.i8; break;
+ case nsXPTType::T_I16 : *((int16_t*) d) = s->val.i16; break;
+ case nsXPTType::T_I32 : *((int32_t*) d) = s->val.i32; break;
+ case nsXPTType::T_I64 : *((int64_t*) d) = s->val.i64; d++; break;
+ case nsXPTType::T_U8 : *((uint8_t*) d) = s->val.u8; break;
+ case nsXPTType::T_U16 : *((uint16_t*)d) = s->val.u16; break;
+ case nsXPTType::T_U32 : *((uint32_t*)d) = s->val.u32; break;
+ case nsXPTType::T_U64 : *((uint64_t*)d) = s->val.u64; d++; break;
+ case nsXPTType::T_FLOAT : *((float*) d) = s->val.f; break;
+ case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; break;
+ case nsXPTType::T_BOOL : *((bool*) d) = s->val.b; break;
+ case nsXPTType::T_CHAR : *((char*) d) = s->val.c; break;
+ case nsXPTType::T_WCHAR : *((wchar_t*) d) = s->val.wc; break;
+ default:
+ // all the others are plain pointer types
+ *((void**)d) = s->val.p;
+ break;
+ }
+ }
+}
+} // extern "C"
+
+/*
+ EXPORT_XPCOM_API(nsresult)
+ NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
+ uint32_t paramCount, nsXPTCVariant* params);
+
+ Each param takes at most two 4-byte words.
+ It doesn't matter if we push too many words, and calculating the exact
+ amount takes time.
+
+ that = ebp + 0x08
+ methodIndex = ebp + 0x0c
+ paramCount = ebp + 0x10
+ params = ebp + 0x14
+
+*/
+
+__asm__ (
+ ".text\n\t"
+/* alignment here seems unimportant here; this was 16, now it's 2 which
+ is what xptcstubs uses. */
+ ".align 2\n\t"
+ ".globl _NS_InvokeByIndex\n\t"
+ "_NS_InvokeByIndex:\n\t"
+ "pushl %ebp\n\t"
+ "movl %esp, %ebp\n\t"
+ "movl 0x10(%ebp), %eax\n\t"
+ "leal 0(,%eax,8),%edx\n\t"
+
+ /* set up call frame for method. */
+ "subl %edx, %esp\n\t" /* make room for params. */
+/* Align to maximum x86 data size: 128 bits == 16 bytes == XMM register size.
+ * This is to avoid protection faults where SSE+ alignment of stack pointer
+ * is assumed and required, e.g. by GCC4's -ftree-vectorize option.
+ */
+ "andl $0xfffffff0, %esp\n\t" /* drop(?) stack ptr to 128-bit align */
+/* $esp should be aligned to a 16-byte boundary here (note we include an
+ * additional 4 bytes in a later push instruction). This will ensure $ebp
+ * in the function called below is aligned to a 0x8 boundary. SSE instructions
+ * like movapd/movdqa expect memory operand to be aligned on a 16-byte
+ * boundary. The GCC compiler will generate the memory operand using $ebp
+ * with an 8-byte offset.
+ */
+ "subl $0xc, %esp\n\t" /* lower again; push/call below will re-align */
+ "movl %esp, %ecx\n\t" /* ecx = d */
+ "movl 8(%ebp), %edx\n\t" /* edx = this */
+ "pushl %edx\n\t" /* push this. esp % 16 == 0 */
+
+ "movl 0x14(%ebp), %edx\n\t"
+ "call _invoke_copy_to_stack\n\t"
+ "movl 0x08(%ebp), %ecx\n\t" /* 'that' */
+ "movl (%ecx), %edx\n\t"
+ "movl 0x0c(%ebp), %eax\n\t" /* function index */
+ "leal (%edx,%eax,4), %edx\n\t"
+ "call *(%edx)\n\t"
+ "movl %ebp, %esp\n\t"
+ "popl %ebp\n\t"
+ "ret\n"
+ ".section .drectve\n\t"
+ ".ascii \" -export:NS_InvokeByIndex\"\n\t"
+ ".text\n\t"
+);
diff --git a/xpcom/reflect/xptcall/md/win32/xptcstubs.cpp b/xpcom/reflect/xptcall/md/win32/xptcstubs.cpp
new file mode 100644
index 000000000..e525aebd7
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcstubs.cpp
@@ -0,0 +1,227 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Implement shared vtbl methods. */
+
+#include "xptcprivate.h"
+#include "xptiprivate.h"
+
+#ifndef WIN32
+#error "This code is for Win32 only"
+#endif
+
+extern "C" {
+
+#if !defined(__GNUC__) && !defined(__clang__)
+static
+#endif
+nsresult __stdcall
+PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
+ uint32_t* args, uint32_t* stackBytesToPop)
+{
+#define PARAM_BUFFER_COUNT 16
+
+ nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
+ nsXPTCMiniVariant* dispatchParams = nullptr;
+ const nsXPTMethodInfo* info = nullptr;
+ uint8_t paramCount;
+ uint8_t i;
+ nsresult result = NS_ERROR_FAILURE;
+
+ // If anything fails before stackBytesToPop can be set then
+ // the failure is completely catastrophic!
+
+ NS_ASSERTION(self,"no self");
+
+ self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
+ NS_ASSERTION(info,"no method info");
+
+ paramCount = info->GetParamCount();
+
+ // setup variant array pointer
+ if(paramCount > PARAM_BUFFER_COUNT)
+ dispatchParams = new nsXPTCMiniVariant[paramCount];
+ else
+ dispatchParams = paramBuffer;
+ NS_ASSERTION(dispatchParams,"no place for params");
+
+ uint32_t* ap = args;
+ for(i = 0; i < paramCount; i++, ap++)
+ {
+ const nsXPTParamInfo& param = info->GetParam(i);
+ const nsXPTType& type = param.GetType();
+ nsXPTCMiniVariant* dp = &dispatchParams[i];
+
+ if(param.IsOut() || !type.IsArithmetic())
+ {
+ dp->val.p = (void*) *ap;
+ continue;
+ }
+ // else
+ switch(type)
+ {
+ case nsXPTType::T_I8 : dp->val.i8 = *((int8_t*) ap); break;
+ case nsXPTType::T_I16 : dp->val.i16 = *((int16_t*) ap); break;
+ case nsXPTType::T_I32 : dp->val.i32 = *((int32_t*) ap); break;
+ case nsXPTType::T_I64 : dp->val.i64 = *((int64_t*) ap); ap++; break;
+ case nsXPTType::T_U8 : dp->val.u8 = *((uint8_t*) ap); break;
+ case nsXPTType::T_U16 : dp->val.u16 = *((uint16_t*)ap); break;
+ case nsXPTType::T_U32 : dp->val.u32 = *((uint32_t*)ap); break;
+ case nsXPTType::T_U64 : dp->val.u64 = *((uint64_t*)ap); ap++; break;
+ case nsXPTType::T_FLOAT : dp->val.f = *((float*) ap); break;
+ case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); ap++; break;
+ case nsXPTType::T_BOOL : dp->val.b = *((bool*) ap); break;
+ case nsXPTType::T_CHAR : dp->val.c = *((char*) ap); break;
+ case nsXPTType::T_WCHAR : dp->val.wc = *((wchar_t*) ap); break;
+ default:
+ NS_ERROR("bad type");
+ break;
+ }
+ }
+ *stackBytesToPop = ((uint32_t)ap) - ((uint32_t)args);
+
+ result = self->mOuter->CallMethod((uint16_t)methodIndex, info, dispatchParams);
+
+ if(dispatchParams != paramBuffer)
+ delete [] dispatchParams;
+
+ return result;
+}
+
+} // extern "C"
+
+// declspec(naked) is broken in gcc and clang-cl
+#if !defined(__GNUC__) && !defined(__clang__)
+static
+__declspec(naked)
+void SharedStub(void)
+{
+ __asm {
+ push ebp // set up simple stack frame
+ mov ebp, esp // stack has: ebp/vtbl_index/retaddr/this/args
+ push ecx // make room for a ptr
+ lea eax, [ebp-4] // pointer to stackBytesToPop
+ push eax
+ lea eax, [ebp+12] // pointer to args
+ push eax
+ push ecx // vtbl_index
+ mov eax, [ebp+8] // this
+ push eax
+ call PrepareAndDispatch
+ mov edx, [ebp+4] // return address
+ mov ecx, [ebp-4] // stackBytesToPop
+ add ecx, 8 // for 'this' and return address
+ mov esp, ebp
+ pop ebp
+ add esp, ecx // fix up stack pointer
+ jmp edx // simulate __stdcall return
+ }
+}
+
+// these macros get expanded (many times) in the file #included below
+#define STUB_ENTRY(n) \
+__declspec(naked) nsresult __stdcall nsXPTCStubBase::Stub##n() \
+{ __asm mov ecx, n __asm jmp SharedStub }
+
+#else
+
+asm(".text\n\t"
+ ".align 4\n\t"
+ "SharedStub:\n\t"
+ "push %ebp\n\t"
+ "mov %esp, %ebp\n\t"
+ "push %ecx\n\t"
+ "lea -4(%ebp), %eax\n\t"
+ "push %eax\n\t"
+ "lea 12(%ebp), %eax\n\t"
+ "push %eax\n\t"
+ "push %ecx\n\t"
+ "movl 8(%ebp), %eax\n\t"
+ "push %eax\n\t"
+ "call _PrepareAndDispatch@16\n\t"
+ "mov 4(%ebp), %edx\n\t"
+ "mov -4(%ebp), %ecx\n\t"
+ "add $8, %ecx\n\t"
+ "mov %ebp, %esp\n\t"
+ "pop %ebp\n\t"
+ "add %ecx, %esp\n\t"
+ "jmp *%edx"
+);
+
+// The clang-cl specific code below is required because mingw uses the gcc name
+// mangling, but clang-cl implements the MSVC name mangling.
+
+#ifdef __clang__
+
+#define STUB_ENTRY(n) \
+asm(".text\n\t" \
+ ".align 4\n\t" \
+ ".globl \"?Stub" #n "@nsXPTCStubBase@@UAG?AW4nsresult@@XZ\"\n\t" \
+ ".def \"?Stub" #n "@nsXPTCStubBase@@UAG?AW4nsresult@@XZ\"; \n\t" \
+ ".scl 2\n\t" \
+ ".type 46\n\t" \
+ ".endef\n\t" \
+ "\"?Stub" #n "@nsXPTCStubBase@@UAG?AW4nsresult@@XZ\":\n\t" \
+ "mov $" #n ", %ecx\n\t" \
+ "jmp SharedStub");
+
+#else
+
+#define STUB_ENTRY(n) \
+asm(".text\n\t" \
+ ".align 4\n\t" \
+ ".if " #n " < 10\n\t" \
+ ".globl __ZN14nsXPTCStubBase5Stub" #n "Ev@4\n\t" \
+ ".def __ZN14nsXPTCStubBase5Stub" #n "Ev@4; \n\t" \
+ ".scl 3\n\t" \
+ ".type 46\n\t" \
+ ".endef\n\t" \
+ "__ZN14nsXPTCStubBase5Stub" #n "Ev@4:\n\t" \
+ ".elseif " #n " < 100\n\t" \
+ ".globl __ZN14nsXPTCStubBase6Stub" #n "Ev@4\n\t" \
+ ".def __ZN14nsXPTCStubBase6Stub" #n "Ev@4\n\t" \
+ ".scl 3\n\t" \
+ ".type 46\n\t" \
+ ".endef\n\t" \
+ "__ZN14nsXPTCStubBase6Stub" #n "Ev@4:\n\t" \
+ ".elseif " #n " < 1000\n\t" \
+ ".globl __ZN14nsXPTCStubBase7Stub" #n "Ev@4\n\t" \
+ ".def __ZN14nsXPTCStubBase7Stub" #n "Ev@4\n\t" \
+ ".scl 3\n\t" \
+ ".type 46\n\t" \
+ ".endef\n\t" \
+ "__ZN14nsXPTCStubBase7Stub" #n "Ev@4:\n\t" \
+ ".else\n\t" \
+ ".err \"stub number " #n " >= 1000 not yet supported\"\n\t" \
+ ".endif\n\t" \
+ "mov $" #n ", %ecx\n\t" \
+ "jmp SharedStub");
+
+#endif
+
+#endif /* __GNUC__ || __clang__ */
+
+#define SENTINEL_ENTRY(n) \
+nsresult __stdcall nsXPTCStubBase::Sentinel##n() \
+{ \
+ NS_ERROR("nsXPTCStubBase::Sentinel called"); \
+ return NS_ERROR_NOT_IMPLEMENTED; \
+}
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4035) // OK to have no return value
+#endif
+#include "xptcstubsdef.inc"
+#ifdef _MSC_VER
+#pragma warning(default : 4035) // restore default
+#endif
+
+void
+#ifdef __GNUC__
+__cdecl
+#endif
+xptc_dummy()
+{
+}
diff --git a/xpcom/reflect/xptcall/md/win32/xptcstubs_asm_x86_64.asm b/xpcom/reflect/xptcall/md/win32/xptcstubs_asm_x86_64.asm
new file mode 100644
index 000000000..db2cc16be
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcstubs_asm_x86_64.asm
@@ -0,0 +1,335 @@
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+extrn PrepareAndDispatch:PROC
+
+.code
+
+SharedStub PROC FRAME
+ sub rsp, 104
+ .ALLOCSTACK 104
+ .ENDPROLOG
+
+ ; rcx is this pointer. Need backup for optimized build
+
+ mov qword ptr [rsp+88], rcx
+
+ ;
+ ; fist 4 parameters (1st is "this" pointer) are passed in registers.
+ ;
+
+ ; for floating value
+
+ movsd qword ptr [rsp+64], xmm1
+ movsd qword ptr [rsp+72], xmm2
+ movsd qword ptr [rsp+80], xmm3
+
+ ; for integer value
+
+ mov qword ptr [rsp+40], rdx
+ mov qword ptr [rsp+48], r8
+ mov qword ptr [rsp+56], r9
+
+ ;
+ ; Call PrepareAndDispatch function
+ ;
+
+ ; 5th parameter (floating parameters) of PrepareAndDispatch
+
+ lea r9, qword ptr [rsp+64]
+ mov qword ptr [rsp+32], r9
+
+ ; 4th parameter (normal parameters) of PrepareAndDispatch
+
+ lea r9, qword ptr [rsp+40]
+
+ ; 3rd parameter (pointer to args on stack)
+
+ lea r8, qword ptr [rsp+40+104]
+
+ ; 2nd parameter (vtbl_index)
+
+ mov rdx, r11
+
+ ; 1st parameter (this) (rcx)
+
+ call PrepareAndDispatch
+
+ ; restore rcx
+
+ mov rcx, qword ptr [rsp+88]
+
+ ;
+ ; clean up register
+ ;
+
+ add rsp, 104+8
+
+ ; set return address
+
+ mov rdx, qword ptr [rsp-8]
+
+ ; simulate __stdcall return
+
+ jmp rdx
+
+SharedStub ENDP
+
+
+STUBENTRY MACRO functionname, paramcount
+functionname PROC
+ mov r11, paramcount
+ jmp SharedStub
+functionname ENDP
+ENDM
+
+ STUBENTRY ?Stub3@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 3
+ STUBENTRY ?Stub4@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 4
+ STUBENTRY ?Stub5@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 5
+ STUBENTRY ?Stub6@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 6
+ STUBENTRY ?Stub7@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 7
+ STUBENTRY ?Stub8@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 8
+ STUBENTRY ?Stub9@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 9
+ STUBENTRY ?Stub10@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 10
+ STUBENTRY ?Stub11@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 11
+ STUBENTRY ?Stub12@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 12
+ STUBENTRY ?Stub13@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 13
+ STUBENTRY ?Stub14@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 14
+ STUBENTRY ?Stub15@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 15
+ STUBENTRY ?Stub16@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 16
+ STUBENTRY ?Stub17@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 17
+ STUBENTRY ?Stub18@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 18
+ STUBENTRY ?Stub19@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 19
+ STUBENTRY ?Stub20@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 20
+ STUBENTRY ?Stub21@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 21
+ STUBENTRY ?Stub22@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 22
+ STUBENTRY ?Stub23@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 23
+ STUBENTRY ?Stub24@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 24
+ STUBENTRY ?Stub25@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 25
+ STUBENTRY ?Stub26@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 26
+ STUBENTRY ?Stub27@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 27
+ STUBENTRY ?Stub28@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 28
+ STUBENTRY ?Stub29@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 29
+ STUBENTRY ?Stub30@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 30
+ STUBENTRY ?Stub31@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 31
+ STUBENTRY ?Stub32@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 32
+ STUBENTRY ?Stub33@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 33
+ STUBENTRY ?Stub34@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 34
+ STUBENTRY ?Stub35@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 35
+ STUBENTRY ?Stub36@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 36
+ STUBENTRY ?Stub37@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 37
+ STUBENTRY ?Stub38@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 38
+ STUBENTRY ?Stub39@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 39
+ STUBENTRY ?Stub40@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 40
+ STUBENTRY ?Stub41@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 41
+ STUBENTRY ?Stub42@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 42
+ STUBENTRY ?Stub43@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 43
+ STUBENTRY ?Stub44@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 44
+ STUBENTRY ?Stub45@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 45
+ STUBENTRY ?Stub46@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 46
+ STUBENTRY ?Stub47@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 47
+ STUBENTRY ?Stub48@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 48
+ STUBENTRY ?Stub49@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 49
+ STUBENTRY ?Stub50@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 50
+ STUBENTRY ?Stub51@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 51
+ STUBENTRY ?Stub52@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 52
+ STUBENTRY ?Stub53@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 53
+ STUBENTRY ?Stub54@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 54
+ STUBENTRY ?Stub55@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 55
+ STUBENTRY ?Stub56@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 56
+ STUBENTRY ?Stub57@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 57
+ STUBENTRY ?Stub58@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 58
+ STUBENTRY ?Stub59@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 59
+ STUBENTRY ?Stub60@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 60
+ STUBENTRY ?Stub61@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 61
+ STUBENTRY ?Stub62@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 62
+ STUBENTRY ?Stub63@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 63
+ STUBENTRY ?Stub64@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 64
+ STUBENTRY ?Stub65@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 65
+ STUBENTRY ?Stub66@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 66
+ STUBENTRY ?Stub67@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 67
+ STUBENTRY ?Stub68@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 68
+ STUBENTRY ?Stub69@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 69
+ STUBENTRY ?Stub70@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 70
+ STUBENTRY ?Stub71@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 71
+ STUBENTRY ?Stub72@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 72
+ STUBENTRY ?Stub73@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 73
+ STUBENTRY ?Stub74@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 74
+ STUBENTRY ?Stub75@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 75
+ STUBENTRY ?Stub76@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 76
+ STUBENTRY ?Stub77@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 77
+ STUBENTRY ?Stub78@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 78
+ STUBENTRY ?Stub79@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 79
+ STUBENTRY ?Stub80@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 80
+ STUBENTRY ?Stub81@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 81
+ STUBENTRY ?Stub82@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 82
+ STUBENTRY ?Stub83@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 83
+ STUBENTRY ?Stub84@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 84
+ STUBENTRY ?Stub85@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 85
+ STUBENTRY ?Stub86@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 86
+ STUBENTRY ?Stub87@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 87
+ STUBENTRY ?Stub88@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 88
+ STUBENTRY ?Stub89@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 89
+ STUBENTRY ?Stub90@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 90
+ STUBENTRY ?Stub91@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 91
+ STUBENTRY ?Stub92@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 92
+ STUBENTRY ?Stub93@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 93
+ STUBENTRY ?Stub94@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 94
+ STUBENTRY ?Stub95@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 95
+ STUBENTRY ?Stub96@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 96
+ STUBENTRY ?Stub97@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 97
+ STUBENTRY ?Stub98@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 98
+ STUBENTRY ?Stub99@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 99
+ STUBENTRY ?Stub100@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 100
+ STUBENTRY ?Stub101@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 101
+ STUBENTRY ?Stub102@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 102
+ STUBENTRY ?Stub103@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 103
+ STUBENTRY ?Stub104@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 104
+ STUBENTRY ?Stub105@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 105
+ STUBENTRY ?Stub106@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 106
+ STUBENTRY ?Stub107@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 107
+ STUBENTRY ?Stub108@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 108
+ STUBENTRY ?Stub109@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 109
+ STUBENTRY ?Stub110@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 110
+ STUBENTRY ?Stub111@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 111
+ STUBENTRY ?Stub112@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 112
+ STUBENTRY ?Stub113@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 113
+ STUBENTRY ?Stub114@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 114
+ STUBENTRY ?Stub115@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 115
+ STUBENTRY ?Stub116@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 116
+ STUBENTRY ?Stub117@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 117
+ STUBENTRY ?Stub118@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 118
+ STUBENTRY ?Stub119@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 119
+ STUBENTRY ?Stub120@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 120
+ STUBENTRY ?Stub121@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 121
+ STUBENTRY ?Stub122@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 122
+ STUBENTRY ?Stub123@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 123
+ STUBENTRY ?Stub124@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 124
+ STUBENTRY ?Stub125@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 125
+ STUBENTRY ?Stub126@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 126
+ STUBENTRY ?Stub127@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 127
+ STUBENTRY ?Stub128@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 128
+ STUBENTRY ?Stub129@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 129
+ STUBENTRY ?Stub130@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 130
+ STUBENTRY ?Stub131@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 131
+ STUBENTRY ?Stub132@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 132
+ STUBENTRY ?Stub133@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 133
+ STUBENTRY ?Stub134@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 134
+ STUBENTRY ?Stub135@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 135
+ STUBENTRY ?Stub136@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 136
+ STUBENTRY ?Stub137@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 137
+ STUBENTRY ?Stub138@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 138
+ STUBENTRY ?Stub139@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 139
+ STUBENTRY ?Stub140@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 140
+ STUBENTRY ?Stub141@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 141
+ STUBENTRY ?Stub142@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 142
+ STUBENTRY ?Stub143@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 143
+ STUBENTRY ?Stub144@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 144
+ STUBENTRY ?Stub145@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 145
+ STUBENTRY ?Stub146@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 146
+ STUBENTRY ?Stub147@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 147
+ STUBENTRY ?Stub148@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 148
+ STUBENTRY ?Stub149@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 149
+ STUBENTRY ?Stub150@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 150
+ STUBENTRY ?Stub151@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 151
+ STUBENTRY ?Stub152@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 152
+ STUBENTRY ?Stub153@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 153
+ STUBENTRY ?Stub154@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 154
+ STUBENTRY ?Stub155@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 155
+ STUBENTRY ?Stub156@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 156
+ STUBENTRY ?Stub157@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 157
+ STUBENTRY ?Stub158@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 158
+ STUBENTRY ?Stub159@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 159
+ STUBENTRY ?Stub160@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 160
+ STUBENTRY ?Stub161@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 161
+ STUBENTRY ?Stub162@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 162
+ STUBENTRY ?Stub163@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 163
+ STUBENTRY ?Stub164@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 164
+ STUBENTRY ?Stub165@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 165
+ STUBENTRY ?Stub166@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 166
+ STUBENTRY ?Stub167@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 167
+ STUBENTRY ?Stub168@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 168
+ STUBENTRY ?Stub169@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 169
+ STUBENTRY ?Stub170@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 170
+ STUBENTRY ?Stub171@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 171
+ STUBENTRY ?Stub172@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 172
+ STUBENTRY ?Stub173@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 173
+ STUBENTRY ?Stub174@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 174
+ STUBENTRY ?Stub175@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 175
+ STUBENTRY ?Stub176@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 176
+ STUBENTRY ?Stub177@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 177
+ STUBENTRY ?Stub178@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 178
+ STUBENTRY ?Stub179@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 179
+ STUBENTRY ?Stub180@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 180
+ STUBENTRY ?Stub181@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 181
+ STUBENTRY ?Stub182@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 182
+ STUBENTRY ?Stub183@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 183
+ STUBENTRY ?Stub184@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 184
+ STUBENTRY ?Stub185@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 185
+ STUBENTRY ?Stub186@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 186
+ STUBENTRY ?Stub187@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 187
+ STUBENTRY ?Stub188@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 188
+ STUBENTRY ?Stub189@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 189
+ STUBENTRY ?Stub190@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 190
+ STUBENTRY ?Stub191@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 191
+ STUBENTRY ?Stub192@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 192
+ STUBENTRY ?Stub193@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 193
+ STUBENTRY ?Stub194@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 194
+ STUBENTRY ?Stub195@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 195
+ STUBENTRY ?Stub196@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 196
+ STUBENTRY ?Stub197@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 197
+ STUBENTRY ?Stub198@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 198
+ STUBENTRY ?Stub199@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 199
+ STUBENTRY ?Stub200@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 200
+ STUBENTRY ?Stub201@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 201
+ STUBENTRY ?Stub202@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 202
+ STUBENTRY ?Stub203@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 203
+ STUBENTRY ?Stub204@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 204
+ STUBENTRY ?Stub205@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 205
+ STUBENTRY ?Stub206@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 206
+ STUBENTRY ?Stub207@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 207
+ STUBENTRY ?Stub208@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 208
+ STUBENTRY ?Stub209@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 209
+ STUBENTRY ?Stub210@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 210
+ STUBENTRY ?Stub211@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 211
+ STUBENTRY ?Stub212@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 212
+ STUBENTRY ?Stub213@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 213
+ STUBENTRY ?Stub214@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 214
+ STUBENTRY ?Stub215@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 215
+ STUBENTRY ?Stub216@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 216
+ STUBENTRY ?Stub217@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 217
+ STUBENTRY ?Stub218@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 218
+ STUBENTRY ?Stub219@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 219
+ STUBENTRY ?Stub220@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 220
+ STUBENTRY ?Stub221@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 221
+ STUBENTRY ?Stub222@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 222
+ STUBENTRY ?Stub223@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 223
+ STUBENTRY ?Stub224@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 224
+ STUBENTRY ?Stub225@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 225
+ STUBENTRY ?Stub226@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 226
+ STUBENTRY ?Stub227@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 227
+ STUBENTRY ?Stub228@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 228
+ STUBENTRY ?Stub229@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 229
+ STUBENTRY ?Stub230@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 230
+ STUBENTRY ?Stub231@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 231
+ STUBENTRY ?Stub232@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 232
+ STUBENTRY ?Stub233@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 233
+ STUBENTRY ?Stub234@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 234
+ STUBENTRY ?Stub235@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 235
+ STUBENTRY ?Stub236@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 236
+ STUBENTRY ?Stub237@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 237
+ STUBENTRY ?Stub238@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 238
+ STUBENTRY ?Stub239@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 239
+ STUBENTRY ?Stub240@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 240
+ STUBENTRY ?Stub241@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 241
+ STUBENTRY ?Stub242@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 242
+ STUBENTRY ?Stub243@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 243
+ STUBENTRY ?Stub244@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 244
+ STUBENTRY ?Stub245@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 245
+ STUBENTRY ?Stub246@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 246
+ STUBENTRY ?Stub247@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 247
+ STUBENTRY ?Stub248@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 248
+ STUBENTRY ?Stub249@nsXPTCStubBase@@UEAA?AW4nsresult@@XZ, 249
+
+END
diff --git a/xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64.cpp b/xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64.cpp
new file mode 100644
index 000000000..8ff479d1e
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64.cpp
@@ -0,0 +1,197 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Implement shared vtbl methods. */
+
+#include "xptcprivate.h"
+#include "xptiprivate.h"
+
+/*
+ * This is for Windows XP 64-Bit Edition / Server 2003 for AMD64 or later.
+ */
+
+extern "C" nsresult
+PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args,
+ uint64_t *gprData, double *fprData)
+{
+#define PARAM_BUFFER_COUNT 16
+//
+// "this" pointer is first parameter, so parameter count is 3.
+//
+#define PARAM_GPR_COUNT 3
+#define PARAM_FPR_COUNT 3
+
+ nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
+ nsXPTCMiniVariant* dispatchParams = nullptr;
+ const nsXPTMethodInfo* info = nullptr;
+ uint8_t paramCount;
+ uint8_t i;
+ nsresult result = NS_ERROR_FAILURE;
+
+ NS_ASSERTION(self,"no self");
+
+ self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
+ NS_ASSERTION(info,"no method info");
+
+ paramCount = info->GetParamCount();
+
+ //
+ // setup variant array pointer
+ //
+
+ if(paramCount > PARAM_BUFFER_COUNT)
+ dispatchParams = new nsXPTCMiniVariant[paramCount];
+ else
+ dispatchParams = paramBuffer;
+
+ NS_ASSERTION(dispatchParams,"no place for params");
+
+ uint64_t* ap = args;
+ uint32_t iCount = 0;
+
+ for(i = 0; i < paramCount; i++)
+ {
+ const nsXPTParamInfo& param = info->GetParam(i);
+ const nsXPTType& type = param.GetType();
+ nsXPTCMiniVariant* dp = &dispatchParams[i];
+
+ if(param.IsOut() || !type.IsArithmetic())
+ {
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.p = (void*)gprData[iCount++];
+ else
+ dp->val.p = (void*)*ap++;
+
+ continue;
+ }
+ // else
+ switch(type)
+ {
+ case nsXPTType::T_I8:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.i8 = (int8_t)gprData[iCount++];
+ else
+ dp->val.i8 = *((int8_t*)ap++);
+ break;
+
+ case nsXPTType::T_I16:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.i16 = (int16_t)gprData[iCount++];
+ else
+ dp->val.i16 = *((int16_t*)ap++);
+ break;
+
+ case nsXPTType::T_I32:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.i32 = (int32_t)gprData[iCount++];
+ else
+ dp->val.i32 = *((int32_t*)ap++);
+ break;
+
+ case nsXPTType::T_I64:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.i64 = (int64_t)gprData[iCount++];
+ else
+ dp->val.i64 = *((int64_t*)ap++);
+ break;
+
+ case nsXPTType::T_U8:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.u8 = (uint8_t)gprData[iCount++];
+ else
+ dp->val.u8 = *((uint8_t*)ap++);
+ break;
+
+ case nsXPTType::T_U16:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.u16 = (uint16_t)gprData[iCount++];
+ else
+ dp->val.u16 = *((uint16_t*)ap++);
+ break;
+
+ case nsXPTType::T_U32:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.u32 = (uint32_t)gprData[iCount++];
+ else
+ dp->val.u32 = *((uint32_t*)ap++);
+ break;
+
+ case nsXPTType::T_U64:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.u64 = (uint64_t)gprData[iCount++];
+ else
+ dp->val.u64 = *((uint64_t*)ap++);
+ break;
+
+ case nsXPTType::T_FLOAT:
+ if (iCount < PARAM_FPR_COUNT)
+ // The value in xmm register is already prepared to
+ // be retrieved as a float. Therefore, we pass the
+ // value verbatim, as a double without conversion.
+ dp->val.d = (double)fprData[iCount++];
+ else
+ dp->val.f = *((float*)ap++);
+ break;
+
+ case nsXPTType::T_DOUBLE:
+ if (iCount < PARAM_FPR_COUNT)
+ dp->val.d = (double)fprData[iCount++];
+ else
+ dp->val.d = *((double*)ap++);
+ break;
+
+ case nsXPTType::T_BOOL:
+ if (iCount < PARAM_GPR_COUNT)
+ // We need cast to uint8_t to remove garbage on upper 56-bit
+ // at first.
+ dp->val.b = (bool)(uint8_t)gprData[iCount++];
+ else
+ dp->val.b = *((bool*)ap++);
+ break;
+
+ case nsXPTType::T_CHAR:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.c = (char)gprData[iCount++];
+ else
+ dp->val.c = *((char*)ap++);
+ break;
+
+ case nsXPTType::T_WCHAR:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.wc = (wchar_t)gprData[iCount++];
+ else
+ dp->val.wc = *((wchar_t*)ap++);
+ break;
+
+ default:
+ NS_ERROR("bad type");
+ break;
+ }
+ }
+
+ result = self->mOuter->CallMethod((uint16_t)methodIndex, info, dispatchParams);
+
+ if(dispatchParams != paramBuffer)
+ delete [] dispatchParams;
+
+ return result;
+}
+
+#define STUB_ENTRY(n) /* defined in the assembly file */
+
+#define SENTINEL_ENTRY(n) \
+nsresult nsXPTCStubBase::Sentinel##n() \
+{ \
+ NS_ERROR("nsXPTCStubBase::Sentinel called"); \
+ return NS_ERROR_NOT_IMPLEMENTED; \
+}
+
+#include "xptcstubsdef.inc"
+
+void
+xptc_dummy()
+{
+}
+
diff --git a/xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64_gnu.cpp b/xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64_gnu.cpp
new file mode 100644
index 000000000..2676334d2
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64_gnu.cpp
@@ -0,0 +1,297 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xptcprivate.h"
+#include "xptiprivate.h"
+
+/*
+ * This is for Windows 64 bit (x86_64) using GCC syntax
+ * Code was copied from the MSVC version.
+ */
+
+#if !defined(_AMD64_) || !defined(__GNUC__)
+# error xptcstubs_x86_64_gnu.cpp being used unexpectedly
+#endif
+
+extern "C" nsresult __attribute__((__used__))
+PrepareAndDispatch(nsXPTCStubBase * self, uint32_t methodIndex,
+ uint64_t * args, uint64_t * gprData, double *fprData)
+{
+#define PARAM_BUFFER_COUNT 16
+//
+// "this" pointer is first parameter, so parameter count is 3.
+//
+#define PARAM_GPR_COUNT 3
+#define PARAM_FPR_COUNT 3
+
+ nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
+ nsXPTCMiniVariant* dispatchParams = nullptr;
+ const nsXPTMethodInfo* info = nullptr;
+ uint8_t paramCount;
+ uint8_t i;
+ nsresult result = NS_ERROR_FAILURE;
+
+ NS_ASSERTION(self, "no self");
+
+ self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
+ NS_ASSERTION(info, "no method info");
+
+ paramCount = info->GetParamCount();
+
+ //
+ // setup variant array pointer
+ //
+
+ if(paramCount > PARAM_BUFFER_COUNT)
+ dispatchParams = new nsXPTCMiniVariant[paramCount];
+ else
+ dispatchParams = paramBuffer;
+
+ NS_ASSERTION(dispatchParams,"no place for params");
+
+ uint64_t* ap = args;
+ uint32_t iCount = 0;
+
+ for(i = 0; i < paramCount; i++)
+ {
+ const nsXPTParamInfo& param = info->GetParam(i);
+ const nsXPTType& type = param.GetType();
+ nsXPTCMiniVariant* dp = &dispatchParams[i];
+
+ if(param.IsOut() || !type.IsArithmetic())
+ {
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.p = (void*)gprData[iCount++];
+ else
+ dp->val.p = (void*)*ap++;
+
+ continue;
+ }
+ // else
+ switch(type)
+ {
+ case nsXPTType::T_I8:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.i8 = (int8_t)gprData[iCount++];
+ else
+ dp->val.i8 = *((int8_t*)ap++);
+ break;
+
+ case nsXPTType::T_I16:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.i16 = (int16_t)gprData[iCount++];
+ else
+ dp->val.i16 = *((int16_t*)ap++);
+ break;
+
+ case nsXPTType::T_I32:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.i32 = (int32_t)gprData[iCount++];
+ else
+ dp->val.i32 = *((int32_t*)ap++);
+ break;
+
+ case nsXPTType::T_I64:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.i64 = (int64_t)gprData[iCount++];
+ else
+ dp->val.i64 = *((int64_t*)ap++);
+ break;
+
+ case nsXPTType::T_U8:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.u8 = (uint8_t)gprData[iCount++];
+ else
+ dp->val.u8 = *((uint8_t*)ap++);
+ break;
+
+ case nsXPTType::T_U16:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.u16 = (uint16_t)gprData[iCount++];
+ else
+ dp->val.u16 = *((uint16_t*)ap++);
+ break;
+
+ case nsXPTType::T_U32:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.u32 = (uint32_t)gprData[iCount++];
+ else
+ dp->val.u32 = *((uint32_t*)ap++);
+ break;
+
+ case nsXPTType::T_U64:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.u64 = (uint64_t)gprData[iCount++];
+ else
+ dp->val.u64 = *((uint64_t*)ap++);
+ break;
+
+ case nsXPTType::T_FLOAT:
+ if (iCount < PARAM_FPR_COUNT)
+ dp->val.f = (float)fprData[iCount++];
+ else
+ dp->val.f = *((float*)ap++);
+ break;
+
+ case nsXPTType::T_DOUBLE:
+ if (iCount < PARAM_FPR_COUNT)
+ dp->val.d = (double)fprData[iCount++];
+ else
+ dp->val.d = *((double*)ap++);
+ break;
+
+ case nsXPTType::T_BOOL:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.b = (bool)gprData[iCount++];
+ else
+ dp->val.b = *((bool*)ap++);
+ break;
+
+ case nsXPTType::T_CHAR:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.c = (char)gprData[iCount++];
+ else
+ dp->val.c = *((char*)ap++);
+ break;
+
+ case nsXPTType::T_WCHAR:
+ if (iCount < PARAM_GPR_COUNT)
+ dp->val.wc = (wchar_t)gprData[iCount++];
+ else
+ dp->val.wc = *((wchar_t*)ap++);
+ break;
+
+ default:
+ NS_ASSERTION(0, "bad type");
+ break;
+ }
+ }
+
+ result = self->mOuter->CallMethod((uint16_t)methodIndex, info, dispatchParams);
+
+ if(dispatchParams != paramBuffer)
+ delete [] dispatchParams;
+
+ return result;
+}
+
+__asm__ (
+ ".text\n"
+ ".intel_syntax noprefix\n" /* switch to Intel syntax to look like the MSVC assembly */
+ ".globl SharedStub\n"
+ ".def SharedStub ; .scl 3 ; .type 46 ; .endef \n"
+ "SharedStub:\n"
+ "sub rsp, 104\n"
+
+ /* rcx is this pointer. Need backup for optimized build */
+
+ "mov qword ptr [rsp+88], rcx\n"
+
+ /*
+ * fist 4 parameters (1st is "this" pointer) are passed in registers.
+ */
+
+ /* for floating value */
+
+ "movsd qword ptr [rsp+64], xmm1\n"
+ "movsd qword ptr [rsp+72], xmm2\n"
+ "movsd qword ptr [rsp+80], xmm3\n"
+
+ /* for integer value */
+
+ "mov qword ptr [rsp+40], rdx\n"
+ "mov qword ptr [rsp+48], r8\n"
+ "mov qword ptr [rsp+56], r9\n"
+
+ /*
+ * Call PrepareAndDispatch function
+ */
+
+ /* 5th parameter (floating parameters) of PrepareAndDispatch */
+
+ "lea r9, qword ptr [rsp+64]\n"
+ "mov qword ptr [rsp+32], r9\n"
+
+ /* 4th parameter (normal parameters) of PrepareAndDispatch */
+
+ "lea r9, qword ptr [rsp+40]\n"
+
+ /* 3rd parameter (pointer to args on stack) */
+
+ "lea r8, qword ptr [rsp+40+104]\n"
+
+ /* 2nd parameter (vtbl_index) */
+
+ "mov rdx, r11\n"
+
+ /* 1st parameter (this) (rcx) */
+
+ "call PrepareAndDispatch\n"
+
+ /* restore rcx */
+
+ "mov rcx, qword ptr [rsp+88]\n"
+
+ /*
+ * clean up register
+ */
+
+ "add rsp, 104+8\n"
+
+ /* set return address */
+
+ "mov rdx, qword ptr [rsp-8]\n"
+
+ /* simulate __stdcall return */
+
+ "jmp rdx\n"
+
+ /* back to AT&T syntax */
+ ".att_syntax\n"
+);
+
+#define STUB_ENTRY(n) \
+asm(".intel_syntax noprefix\n" /* this is in intel syntax */ \
+ ".text\n" \
+ ".align 2\n" \
+ ".if " #n " < 10\n" \
+ ".globl _ZN14nsXPTCStubBase5Stub" #n "Ev@4\n" \
+ ".def _ZN14nsXPTCStubBase5Stub" #n "Ev@4\n" \
+ ".scl 3\n" /* private */ \
+ ".type 46\n" /* function returning unsigned int */ \
+ ".endef\n" \
+ "_ZN14nsXPTCStubBase5Stub" #n "Ev@4:\n" \
+ ".elseif " #n " < 100\n" \
+ ".globl _ZN14nsXPTCStubBase6Stub" #n "Ev@4\n" \
+ ".def _ZN14nsXPTCStubBase6Stub" #n "Ev@4\n" \
+ ".scl 3\n" /* private */\
+ ".type 46\n" /* function returning unsigned int */ \
+ ".endef\n" \
+ "_ZN14nsXPTCStubBase6Stub" #n "Ev@4:\n" \
+ ".elseif " #n " < 1000\n" \
+ ".globl _ZN14nsXPTCStubBase7Stub" #n "Ev@4\n" \
+ ".def _ZN14nsXPTCStubBase7Stub" #n "Ev@4\n" \
+ ".scl 3\n" /* private */ \
+ ".type 46\n" /* function returning unsigned int */ \
+ ".endef\n" \
+ "_ZN14nsXPTCStubBase7Stub" #n "Ev@4:\n" \
+ ".else\n" \
+ ".err \"stub number " #n " >= 1000 not yet supported\"\n" \
+ ".endif\n" \
+ "mov r11, " #n "\n" \
+ "jmp SharedStub\n" \
+ ".att_syntax\n" /* back to AT&T syntax */ \
+ "");
+
+#define SENTINEL_ENTRY(n) \
+nsresult nsXPTCStubBase::Sentinel##n() \
+{ \
+ NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
+ return NS_ERROR_NOT_IMPLEMENTED; \
+}
+
+#include "xptcstubsdef.inc"
+