summaryrefslogtreecommitdiffstats
path: root/xpcom/reflect/xptcall/md/unix
diff options
context:
space:
mode:
authorathenian200 <athenian200@outlook.com>2019-10-01 06:07:31 -0500
committerathenian200 <athenian200@outlook.com>2019-10-21 04:53:39 -0500
commitafc187cc3f907947453b428f857acf16b2b0774e (patch)
tree9ec0854e4c647b96532943b76e215570b0d9f0f4 /xpcom/reflect/xptcall/md/unix
parentc4c4189933f8d610e501cfc8c86dfbe52c4c160d (diff)
downloadUXP-afc187cc3f907947453b428f857acf16b2b0774e.tar
UXP-afc187cc3f907947453b428f857acf16b2b0774e.tar.gz
UXP-afc187cc3f907947453b428f857acf16b2b0774e.tar.lz
UXP-afc187cc3f907947453b428f857acf16b2b0774e.tar.xz
UXP-afc187cc3f907947453b428f857acf16b2b0774e.zip
MoonchildProductions#1251 - Part 1: Restore initial Solaris support, fixed up.
Compared with what Pale Moon had for Solaris originally, this is mostly the same zero point I started patching from, but I've made the following changes here after reviewing all this initial code I never looked at closely before. 1. In package-manifest.in for both Basilisk and Pale Moon, I've made the SPARC code for libfreebl not interefere with the x86 code, use the proper build flags, and also updated it to allow a SPARC64 build which is more likely to be used than the 32-bit SPARC code we had there. 2. See Mozilla bug #832272 and the old rules.mk patch from around Firefox 30 in oracle/solaris-userland. I believe they screwed up NSINSTALL on Solaris when they were trying to streamline the NSS buildsystem, because they started having unexplained issues with it around that time after Firefox 22 that they never properly resolved until Mozilla began building NSS with gyp files. I'm actually not even sure how relevant the thing they broke actually is to Solaris at this point, bug 665509 is so old it predates Firefox itself and goes back to the Mozilla suite days. I believe $(INSTALL) -t was wrong, and they meant $(NSINSTALL) -t because that makes more sense and is closer to what was there originally. It's what they have for WINNT, and it's possible a fix more like that could serve for Solaris as well. Alternatively, we could get rid of all these half-broken Makefiles and start building NSS with gyp files like Mozilla did. 3. I've completely cut out support for the Sun compiler and taken into account the reality that everyone builds Firefox (and therefore its forks) with GCC now on Solaris. This alone helped clean up a lot of the uglier parts of the code. 4. I've updated all remaining SOLARIS build flags to the newer XP_SOLARIS, because the SOLARIS flag is no longer set when building Solaris. 5. I've confirmed the workaround in gtxFontconfigFonts.cpp is no longer necessary. The Solaris people got impatient about implementing a half-baked patch for a fontconfig feature that wasn't ready yet back in 2009, and somehow convinced Mozilla to patch their software to work around it when really they should have just fixed or removed their broken fontconfig patch. The feature they wanted has since been implemented properly, and no version of Solaris still uses the broken patch that required this fix. If anyone had ever properly audited this code, it would have been removed a long time ago.
Diffstat (limited to 'xpcom/reflect/xptcall/md/unix')
-rw-r--r--xpcom/reflect/xptcall/md/unix/moz.build32
-rw-r--r--xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s52
-rw-r--r--xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S122
-rw-r--r--xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp4
-rw-r--r--xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp131
-rw-r--r--xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s49
-rw-r--r--xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp7
-rw-r--r--xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp112
8 files changed, 505 insertions, 4 deletions
diff --git a/xpcom/reflect/xptcall/md/unix/moz.build b/xpcom/reflect/xptcall/md/unix/moz.build
index d455ed854..c5cba0c8d 100644
--- a/xpcom/reflect/xptcall/md/unix/moz.build
+++ b/xpcom/reflect/xptcall/md/unix/moz.build
@@ -46,6 +46,21 @@ if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD'):
'xptcstubs_ipf64.cpp'
]
+# Without the need to accomodate the Sun compiler, Solaris/GCC support is pretty
+# standard, actually. Not all that different from Linux.
+
+if CONFIG['OS_ARCH'] == 'SunOS':
+ if CONFIG['OS_TEST'] == 'x86_64':
+ SOURCES += [
+ 'xptcinvoke_asm_x86_64_unix.S',
+ 'xptcinvoke_x86_64_unix.cpp',
+ 'xptcstubs_x86_64_linux.cpp'
+ ]
+ elif CONFIG['OS_TEST'] == 'x86':
+ SOURCES += [
+ 'xptcinvoke_gcc_x86_unix.cpp',
+ 'xptcstubs_gcc_x86_unix.cpp'
+ ]
if CONFIG['OS_TEST'] == 'alpha':
if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD', 'NetBSD'):
@@ -186,7 +201,11 @@ if CONFIG['OS_ARCH'] == 'OpenBSD' and CONFIG['OS_TEST'] == 'sparc':
'xptcstubs_sparc_openbsd.cpp',
]
-if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD') and CONFIG['OS_TEST'] == 'sparc64':
+# Mozilla discovered at some point that Solaris and Linux can also use these
+# files for 64-bit SPARC with no ill effects, so basically the entire mess that
+# was there before is no longer needed.
+
+if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD', 'SunOS') and CONFIG['OS_TEST'] == 'sparc64':
SOURCES += [
'xptcinvoke_asm_sparc64_openbsd.s',
'xptcinvoke_sparc64_openbsd.cpp',
@@ -194,6 +213,17 @@ if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD') and CONFIG['OS_TEST'] == 'sparc64
'xptcstubs_sparc64_openbsd.cpp',
]
+# As for the 32-bit SPARC build? That would look like the Linux version with
+# one file changed.
+
+if CONFIG['OS_ARCH'] == 'SunOS' and CONFIG['OS_TEST'] == 'sparc':
+ SOURCES += [
+ 'xptcinvoke_asm_sparc_solaris_GCC3.s',
+ 'xptcinvoke_sparc_solaris.cpp',
+ 'xptcstubs_asm_sparc_solaris.s',
+ 'xptcstubs_sparc_solaris.cpp',
+ ]
+
if CONFIG['OS_ARCH'] == 'Linux':
if CONFIG['OS_TEST'] == 's390':
SOURCES += [
diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s
new file mode 100644
index 000000000..54adcd147
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s
@@ -0,0 +1,52 @@
+/* -*- 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 for
+ * solaris/sparc with gcc 3 ABI.
+ */
+ .global NS_InvokeByIndex
+/*
+ * NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
+ * uint32_t paramCount, nsXPTCVariant* params);
+ */
+NS_InvokeByIndex:
+ save %sp,-(64 + 32),%sp ! room for the register window and
+ ! struct pointer, rounded up to 0 % 32
+ mov %i2,%o0 ! paramCount
+ call invoke_count_words ! returns the required stack size in %o0
+ mov %i3,%o1 ! params
+
+ sll %o0,2,%l0 ! number of bytes
+ sub %sp,%l0,%sp ! create the additional stack space
+
+ mov %sp,%o0 ! pointer for copied args
+ add %o0,72,%o0 ! step past the register window, the
+ ! struct result pointer and the 'this' slot
+ mov %i2,%o1 ! paramCount
+ call invoke_copy_to_stack
+ mov %i3,%o2 ! params
+!
+! calculate the target address from the vtable
+!
+ ld [%i0],%l1 ! *that --> vTable
+ sll %i1,2,%i1 ! multiply index by 4
+ add %i1,%l1,%l1 ! l1 now points to vTable entry
+ ld [%l1],%l0 ! target address
+
+.L5: ld [%sp + 88],%o5
+.L4: ld [%sp + 84],%o4
+.L3: ld [%sp + 80],%o3
+.L2: ld [%sp + 76],%o2
+.L1: ld [%sp + 72],%o1
+.L0:
+ jmpl %l0,%o7 ! call the routine
+! always have a 'this', from the incoming 'that'
+ mov %i0,%o0
+
+ mov %o0,%i0 ! propagate return value
+ ret
+ restore
diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S
new file mode 100644
index 000000000..131cfc334
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S
@@ -0,0 +1,122 @@
+# 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/.
+
+# Darwin gives a leading '_' to symbols defined in C code.
+#ifdef XP_DARWIN
+#define SYM(x) _ ## x
+#define CFI_STARTPROC
+#define CFI_ENDPROC
+#define CFI_DEF_CFA_OFFSET(offset)
+#define CFI_OFFSET(reg, offset)
+#define CFI_DEF_CFA_REGISTER(reg)
+#define CFI_DEF_CFA(reg, offset)
+#else
+#define SYM(x) x
+#define CFI_STARTPROC .cfi_startproc
+#define CFI_ENDPROC .cfi_endproc
+#define CFI_DEF_CFA_OFFSET(offset) .cfi_def_cfa_offset offset
+#define CFI_OFFSET(reg, offset) .cfi_offset reg, offset
+#define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
+#define CFI_DEF_CFA(reg, offset) .cfi_def_cfa reg, offset
+#endif
+
+.intel_syntax noprefix
+
+# nsresult NS_InvokeByIndex(nsISupports* this, uint32_t aVtableIndex,
+# uint32_t argc, nsXPTCVariant* argv);
+.text
+.global SYM(NS_InvokeByIndex)
+#ifndef XP_DARWIN
+.type NS_InvokeByIndex, @function
+#endif
+.align 4
+SYM(NS_InvokeByIndex):
+ CFI_STARTPROC
+ push rbp
+ CFI_DEF_CFA_OFFSET(16)
+ CFI_OFFSET(6, -16)
+ mov rbp, rsp
+ CFI_DEF_CFA_REGISTER(6)
+
+# save r12 and r13 because we use them and they are callee saved.
+ push r12
+ push r13
+ CFI_OFFSET(12, -24)
+ CFI_OFFSET(13, -32)
+
+# save this and the vtable index because we need them after setting up the
+# stack.
+ mov r12, rdi
+ mov r13, rsi
+
+# allocate space for stack arguments, in theory we only need 8 * (argc - 5)
+# bytes because at least 5 arguments will go in registers, but for now it is
+# just simpler to allocate 8 * argc bytes. Note that we treat the this
+# pointer specially.
+ lea eax, [edx * 8]
+ sub rsp, rax
+
+# If there is an odd number of args the stack can be misaligned so realign it.
+ and rsp, 0xfffffffffffffff0
+
+# pass the stack slot area to InvokeCopyToStack.
+ mov r8, rsp
+
+# setup space for the register slots: there are 5 integer ones and 8 floating
+# point ones. So we need 104 bytes of space, but we allocate 112 to keep rsp
+# aligned to 16 bytes.
+ sub rsp, 112
+
+# the first argument to InvokeCopyToStack is the integer register area, and the
+# second is the floating point area.
+ mov rdi, rsp
+ lea rsi, [rsp + 40]
+
+# The 3rd and 4th arguments to InvokeCopyToStack are already in the right
+# registers. So now we can just call InvokeCopyToStack.
+ call SYM(InvokeCopyToStack)
+
+# setup this
+ mov rdi, r12
+
+# copy the integer arguments into place.
+ mov rsi, [rsp]
+ mov rdx, [rsp + 8]
+ mov rcx, [rsp + 16]
+ mov r8, [rsp + 24]
+ mov r9, [rsp + 32]
+
+# copy the float arguments into place
+ movsd xmm0, [rsp + 40]
+ movsd xmm1, [rsp + 48]
+ movsd xmm2, [rsp + 56]
+ movsd xmm3, [rsp + 64]
+ movsd xmm4, [rsp + 72]
+ movsd xmm5, [rsp + 80]
+ movsd xmm6, [rsp + 88]
+ movsd xmm7, [rsp + 96]
+
+# get rid of the scratch space for registers
+ add rsp, 112
+
+# load the function pointer and call
+ lea eax, [r13d * 8]
+ add rax, [rdi]
+ call [rax]
+
+# r12 and r13 were pushed relative to the old stack pointer which is now the
+# frame pointer.
+ mov r12, [rbp - 0x8]
+ mov r13, [rbp - 0x10]
+
+ mov rsp, rbp
+ pop rbp
+ CFI_DEF_CFA(7, 8)
+ ret
+ CFI_ENDPROC
+
+#ifndef XP_DARWIN
+// Magic indicating no need for an executable stack
+.section .note.GNU-stack, "", @progbits ; .previous
+#endif
diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp
index 050f9414d..1b5039ed9 100644
--- a/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp
+++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp
@@ -30,9 +30,9 @@ invoke_copy_to_stack(uint64_t* d, uint32_t paramCount, nsXPTCVariant* s)
{
if (regCount < 5) regCount++;
- if (l_s->IsPtrData())
+ if (l_s->IsIndirect())
{
- *l_d = (uint64_t)l_s->ptr;
+ *l_d = (uint64_t) &l_s->val;
continue;
}
switch (l_s->type)
diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp
new file mode 100644
index 000000000..126ef1dad
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp
@@ -0,0 +1,131 @@
+/* -*- 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"
+
+/* solaris defines __sparc for workshop compilers and
+ linux defines __sparc__ */
+
+#if !defined(__sparc) && !defined(__sparc__)
+#error "This code is for Sparc only"
+#endif
+
+typedef unsigned nsXPCVariant;
+
+extern "C" uint32_t
+invoke_count_words(uint32_t paramCount, nsXPTCVariant* s)
+{
+ uint32_t result = 0;
+ for(uint32_t i = 0; i < paramCount; i++, s++)
+ {
+ if(s->IsPtrData())
+ {
+ result++;
+ continue;
+ }
+ switch(s->type)
+ {
+ case nsXPTType::T_I8 :
+ case nsXPTType::T_I16 :
+ case nsXPTType::T_I32 :
+ result++;
+ break;
+ case nsXPTType::T_I64 :
+ result+=2;
+ break;
+ case nsXPTType::T_U8 :
+ case nsXPTType::T_U16 :
+ case nsXPTType::T_U32 :
+ result++;
+ break;
+ case nsXPTType::T_U64 :
+ result+=2;
+ break;
+ case nsXPTType::T_FLOAT :
+ result++;
+ break;
+ case nsXPTType::T_DOUBLE :
+ result+=2;
+ break;
+ case nsXPTType::T_BOOL :
+ case nsXPTType::T_CHAR :
+ case nsXPTType::T_WCHAR :
+ result++;
+ break;
+ default:
+ // all the others are plain pointer types
+ result++;
+ break;
+ }
+ }
+ // nuts, I know there's a cooler way of doing this, but it's late
+ // now and it'll probably come to me in the morning.
+ if (result & 0x3) result += 4 - (result & 0x3); // ensure q-word alignment
+ return result;
+}
+
+extern "C" uint32_t
+invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, nsXPTCVariant* s)
+{
+/*
+ We need to copy the parameters for this function to locals and use them
+ from there since the parameters occupy the same stack space as the stack
+ we're trying to populate.
+*/
+ uint32_t *l_d = d;
+ nsXPTCVariant *l_s = s;
+ uint32_t l_paramCount = paramCount;
+ uint32_t regCount = 0; // return the number of registers to load from the stack
+
+ typedef struct {
+ uint32_t hi;
+ uint32_t lo;
+ } DU; // have to move 64 bit entities as 32 bit halves since
+ // stack slots are not guaranteed 16 byte aligned
+
+ for(uint32_t i = 0; i < l_paramCount; i++, l_d++, l_s++)
+ {
+ if (regCount < 5) regCount++;
+ if(l_s->IsPtrData())
+ {
+ if(l_s->type == nsXPTType::T_JSVAL)
+ {
+ // On SPARC, we need to pass a pointer to HandleValue
+ *((void**)l_d) = &l_s->ptr;
+ } else
+ {
+ *((void**)l_d) = l_s->ptr;
+ }
+ continue;
+ }
+ switch(l_s->type)
+ {
+ case nsXPTType::T_I8 : *((int32_t*) l_d) = l_s->val.i8; break;
+ case nsXPTType::T_I16 : *((int32_t*) l_d) = l_s->val.i16; break;
+ case nsXPTType::T_I32 : *((int32_t*) l_d) = l_s->val.i32; break;
+ case nsXPTType::T_I64 :
+ case nsXPTType::T_U64 :
+ case nsXPTType::T_DOUBLE : *((uint32_t*) l_d++) = ((DU *)l_s)->hi;
+ if (regCount < 5) regCount++;
+ *((uint32_t*) l_d) = ((DU *)l_s)->lo;
+ break;
+ case nsXPTType::T_U8 : *((uint32_t*) l_d) = l_s->val.u8; break;
+ case nsXPTType::T_U16 : *((uint32_t*) l_d) = l_s->val.u16; break;
+ case nsXPTType::T_U32 : *((uint32_t*) l_d) = l_s->val.u32; break;
+ case nsXPTType::T_FLOAT : *((float*) l_d) = l_s->val.f; break;
+ case nsXPTType::T_BOOL : *((uint32_t*) l_d) = l_s->val.b; break;
+ case nsXPTType::T_CHAR : *((uint32_t*) l_d) = l_s->val.c; break;
+ case nsXPTType::T_WCHAR : *((int32_t*) l_d) = l_s->val.wc; break;
+ default:
+ // all the others are plain pointer types
+ *((void**)l_d) = l_s->val.p;
+ break;
+ }
+ }
+ return regCount;
+}
+
diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s b/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s
new file mode 100644
index 000000000..9b448d7c7
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s
@@ -0,0 +1,49 @@
+/* -*- 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/. */
+
+ .global SharedStub
+
+/*
+ in the frame for the function that called SharedStub are the
+ rest of the parameters we need
+
+*/
+
+SharedStub:
+! we don't create a new frame yet, but work within the frame of the calling
+! function to give ourselves the other parameters we want
+
+ mov %o0, %o1 ! shuffle the index up to 2nd place
+ mov %i0, %o0 ! the original 'this'
+ add %fp, 72, %o2 ! previous stack top adjusted to the first argument slot (beyond 'this')
+! save off the original incoming parameters that arrived in
+! registers, the ABI guarantees the space for us to do this
+ st %i1, [%fp + 72]
+ st %i2, [%fp + 76]
+ st %i3, [%fp + 80]
+ st %i4, [%fp + 84]
+ st %i5, [%fp + 88]
+! now we can build our own stack frame
+ save %sp,-(64 + 32),%sp ! room for the register window and
+ ! struct pointer, rounded up to 0 % 32
+! our function now appears to have been called
+! as SharedStub(nsISupports* that, uint32_t index, uint32_t* args)
+! so we can just copy these through
+
+ mov %i0, %o0
+ mov %i1, %o1
+ mov %i2, %o2
+ call PrepareAndDispatch
+ nop
+ mov %o0,%i0 ! propagate return value
+ b .LL1
+ nop
+.LL1:
+ ret
+ restore
+
+ .size SharedStub, .-SharedStub
+ .type SharedStub, #function
diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp
index b8a09c97e..e28a03794 100644
--- a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp
+++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp
@@ -85,8 +85,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args)
extern "C" nsresult SharedStub(int, int*);
+/*
+ * Avoid GCC stack protector to wipe out imput registers since the compiler
+ * thinks the function takes no arguments.
+ */
+
#define STUB_ENTRY(n) \
-nsresult nsXPTCStubBase::Stub##n() \
+nsresult __attribute__((__optimize__("no-stack-protector"))) nsXPTCStubBase::Stub##n() \
{ \
int dummy; /* defeat tail-call optimization */ \
return SharedStub(n, &dummy); \
diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp
new file mode 100644
index 000000000..61f3df4ff
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp
@@ -0,0 +1,112 @@
+/* -*- 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"
+
+#if defined(sparc) || defined(__sparc__)
+
+extern "C" nsresult ATTRIBUTE_USED
+PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
+{
+
+ typedef struct {
+ uint32_t hi;
+ uint32_t lo;
+ } DU; // have to move 64 bit entities as 32 bit halves since
+ // stack slots are not guaranteed 16 byte aligned
+
+#define PARAM_BUFFER_COUNT 16
+
+ nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
+ nsXPTCMiniVariant* dispatchParams = nullptr;
+ const nsXPTMethodInfo* info;
+ 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 interface 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())
+ {
+ if (type == nsXPTType::T_JSVAL)
+ dp->val.p = *((void**) *ap);
+ else
+ dp->val.p = (void*) *ap;
+ continue;
+ }
+ // else
+ switch(type)
+ {
+ case nsXPTType::T_I8 : dp->val.i8 = *((int32_t*) ap); break;
+ case nsXPTType::T_I16 : dp->val.i16 = *((int32_t*) ap); break;
+ case nsXPTType::T_I32 : dp->val.i32 = *((int32_t*) ap); break;
+ case nsXPTType::T_DOUBLE :
+ case nsXPTType::T_U64 :
+ case nsXPTType::T_I64 : ((DU *)dp)->hi = ((DU *)ap)->hi;
+ ((DU *)dp)->lo = ((DU *)ap)->lo;
+ ap++;
+ break;
+ case nsXPTType::T_U8 : dp->val.u8 = *((uint32_t*)ap); break;
+ case nsXPTType::T_U16 : dp->val.u16 = *((uint32_t*)ap); break;
+ case nsXPTType::T_U32 : dp->val.u32 = *((uint32_t*)ap); break;
+ case nsXPTType::T_FLOAT : dp->val.f = *((float*) ap); break;
+ case nsXPTType::T_BOOL : dp->val.b = *((uint32_t*)ap); break;
+ case nsXPTType::T_CHAR : dp->val.c = *((uint32_t*)ap); break;
+ case nsXPTType::T_WCHAR : dp->val.wc = *((int32_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;
+}
+
+extern "C" nsresult SharedStub(int, int*);
+
+#define STUB_ENTRY(n) \
+nsresult nsXPTCStubBase::Stub##n() \
+{ \
+ int dummy; /* defeat tail-call optimization */ \
+ return SharedStub(n, &dummy); \
+}
+
+#define SENTINEL_ENTRY(n) \
+nsresult nsXPTCStubBase::Sentinel##n() \
+{ \
+ NS_ERROR("nsXPTCStubBase::Sentinel called"); \
+ return NS_ERROR_NOT_IMPLEMENTED; \
+}
+
+#include "xptcstubsdef.inc"
+
+#endif /* sparc || __sparc__ */