diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
commit | 16f504a9dca3fe3b70568f67b7d41241ae485288 (patch) | |
tree | c60f36ada0496ba928b7161059ba5ab1ab224f9d /src/libs/xpcom18a4/xpcom/reflect | |
parent | Initial commit. (diff) | |
download | virtualbox-upstream.tar.xz virtualbox-upstream.zip |
Adding upstream version 7.0.6-dfsg.upstream/7.0.6-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
182 files changed, 31363 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/reflect/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/xpcom/reflect/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/Makefile.in new file mode 100644 index 00000000..171900b1 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/Makefile.in @@ -0,0 +1,49 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +DIRS = xptinfo xptcall + +include $(topsrcdir)/config/rules.mk + diff --git a/src/libs/xpcom18a4/xpcom/reflect/Makefile.kup b/src/libs/xpcom18a4/xpcom/reflect/Makefile.kup new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/Makefile.kup diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptcall/.cvsignore new file mode 100644 index 00000000..a1af50c2 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/.cvsignore @@ -0,0 +1,4 @@ +Makefile +mk.bat +set_env.bat +none.pdb diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptcall/Makefile.in new file mode 100644 index 00000000..e3173730 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/Makefile.in @@ -0,0 +1,49 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +DIRS = public src + +include $(topsrcdir)/config/rules.mk + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/Makefile.kup b/src/libs/xpcom18a4/xpcom/reflect/xptcall/Makefile.kup new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/Makefile.kup diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/README b/src/libs/xpcom18a4/xpcom/reflect/xptcall/README new file mode 100644 index 00000000..0c401fe8 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/README @@ -0,0 +1,6 @@ +see: + +http://www.mozilla.org/scriptable/xptcall-faq.html +and +http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/porting.html + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/porting.html b/src/libs/xpcom18a4/xpcom/reflect/xptcall/porting.html new file mode 100644 index 00000000..b8b204a1 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/porting.html @@ -0,0 +1,212 @@ +<html> +<head> +<title>xptcall Porting Guide</title> +</head> +<body bgcolor = "white"> +<h2><center>xptcall Porting Guide</center></h2> + +<h3>Overview</h3> + +<blockquote> + +<a href="http://www.mozilla.org/scriptable/xptcall-faq.html"> xptcall</a> is a +library that supports both invoking methods on arbitrary xpcom objects and +implementing classes whose objects can impersonate any xpcom interface. It does +this using platform specific assembly language code. This code needs to be +ported to all platforms that want to support xptcall (and thus mozilla). + +</blockquote> + +<h3>The tree</h3> + +<blockquote> +<pre> +<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall">mozilla/xpcom/reflect/xptcall</a> + +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public">public</a> // exported headers + +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src">src</a> // core source + | \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md">md</a> // platform specific parts + | +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/mac">mac</a> // mac ppc + | +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> // all unix + | \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32">win32</a> // win32 + | +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/test">test</a> // simple tests to get started + \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/tests">tests</a> // full tests via api +</pre> + +Porters are free to create subdirectories under the base <code>md</code> +directory for their given platforms and to integrate into the build system as +appropriate for their platform. + +</blockquote> + +<h3>Theory of operation</h3> + +<blockquote> + +There are really two pieces of functionality: <i>invoke</i> and <i>stubs</i>... + +<p> + +The <b><i>invoke</i></b> functionality requires the implementation of the +following on each platform (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcall.h#131">xptcall/public/xptcall.h</a>): + +<pre> +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); +</pre> + +Calling code is expected to supply an array of <code>nsXPTCVariant</code> +structs. These are discriminated unions describing the type and value of each +parameter of the target function. The platform specific code then builds a call +frame and invokes the method indicated by the index <code>methodIndex</code> on +the xpcom interface <code>that</code>. + +<p> + +Here are examples of this implementation for +<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32/xptcinvoke.cpp">Win32</a> +and +<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_x86.cpp">Linux x86, NetBSD x86, and FreeBSD</a>. + +Both of these implementations use the basic strategy of: figure out how much +stack space is needed for the params, make the space in a new frame, copy the +params to that space, invoke the method, cleanup and return. C++ is used where +appropriate, Assembly language is used where necessary. Inline assembly language is used here, +but it is equally valid to use separate assembly language source files. Porters +can decide how best to do this for their platforms. + +<p> + +The <b><i>stubs</i></b> functionality is more complex. The goal here is a class +whose vtbl can look like the vtbl of any arbitrary xpcom interface. Objects of +this class can then be built to impersonate any xpcom object. The base interface +for this is (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcall.h#109">xptcall/public/xptcall.h</a>): + +<pre> +class nsXPTCStubBase : public nsISupports +{ +public: + // Include generated vtbl stub declarations. + // These are virtual and *also* implemented by this class.. +#include "xptcstubsdecl.inc" + + // The following methods must be provided by inheritor of this class. + + // return a refcounted pointer to the InterfaceInfo for this object + // NOTE: on some platforms this MUST not fail or we crash! + NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info) = 0; + + // call this method and return result + NS_IMETHOD CallMethod(PRUint16 methodIndex, + const nsXPTMethodInfo* info, + nsXPTCMiniVariant* params) = 0; +}; +</pre> + +Code that wishes to make use of this <i>stubs</i> functionality (such as +<a href="http://www.mozilla.org/scriptable/">XPConnect</a>) implement a class +which inherits from <code>nsXPTCStubBase</code> and implements the +<code>GetInterfaceInfo</code> and <code>CallMethod</code> to let the +platform specific code know how to get interface information and how to dispatch methods +once their parameters have been pulled out of the platform specific calling +frame. + +<p> + +Porters of this functionality implement the platform specific code for the +<i>stub</i> methods that fill the vtbl for this class. The idea here is that the +class has a vtbl full of a large number of generic stubs. All instances of this +class share that vtbl and the same stubs. The stubs forward calls to a platform +specific method that uses the interface information supplied by +the overridden <code>GetInterfaceInfo</code> to extract the parameters and build +an array of platform independent <code>nsXPTCMiniVariant</code> structs which +are in turn passed on to the overridden <code>CallMethod</code>. The +platform dependent code is responsible for doing any cleanup and returning. + +<p> + +The stub methods are declared in <a +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcstubsdecl.inc">xptcall/public/xptcstubsdecl.inc</a>. +These are '#included' into the declaration of <code>nsXPTCStubBase</code>. A +similar include file (<a +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcstubsdef.inc">xptcall/public/xptcstubsdef.inc</a>) +is expanded using platform specific macros to define the stub functions. These +'.inc' files are checked into cvs. However, they can be regenerated as necessary +(i.e. to change the number of stubs or to change their specific declaration) +using the Perl script <a +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/genstubs.pl">xptcall/public/genstubs.pl</a>. + +<p> + +Here are examples of this implementation for <a +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp">Win32</a> +and <a +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unixish_x86.cpp">Linux x86, NetBSD x86, and FreeBSD</a>. +Both of these examples use inline assembly language. That is just how I +decided to do it. You can do it as you choose. + +<p> + +The Win32 version is somewhat tighter because the __declspec(naked) feature +allows for very small stubs. However, the __stdcall requires the callee to clean +up the stack, so it is imperative that the interface information scheme allow +the code to determine the correct stack pointer fixup for return without fail, +else the process will crash. + +<p> + +I opted to use inline assembler for the gcc Linux x86 port. I ended up with +larger stubs than I would have preferred rather than battle the compiler over +what would happen to the stack before my asm code began running. + +<p> + +I believe that the non-assembly parts of these files can be copied and reused +with minimal (but not zero) platform specific tweaks. Feel free to copy and +paste as necessary. Please remember that safety and reliability are more +important than speed optimizations. This code is primarily used to connect XPCOM +components with JavaScript; function call overhead is a <b>tiny</b> part of the +time involved. + +<p> + +I put together +<a +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/test">xptcall/src/md/test +</a> as a place to evolve the basic functionality as a port is coming together. +Not all of the functionality is exercised, but it is a place to get started. +<a +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/tests">xptcall/tests +</a> has an api level test for <code>XPTC_InvokeByIndex</code>, but no tests for +the <i>stubs</i> functionality. Such a test ought to be written, but this has not +yet been done. + +<p> + +A full 'test' at this point requires building the client and running the +XPConnect test called <i>TestXPC</i> in +<a +href="http://lxr.mozilla.org/mozilla/source/js/src/xpconnect/tests">mozilla/js/src/xpconnect/tests +</a>. + +<p> + +Getting these ports done is very important. Please let <a +href="mailto:jband@netscape.com">me</a> know if you are interested in doing one. +I'll answer any questions as I get them. + +<p> + +<a +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/status.html"> +Porting Status +</a> + +</blockquote> + +<hr> +<b>Author:</b> <a href="mailto:jband@netscape.com">John Bandhauer <jband@netscape.com></a><br> +<b>Last modified:</b> 31 May 1999 + +</body> +</html> diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/Makefile.in new file mode 100644 index 00000000..ac8432af --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/Makefile.in @@ -0,0 +1,54 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom + +EXPORTS = \ + xptcall.h \ + xptcstubsdecl.inc \ + xptcstubsdef.inc \ + $(NULL) + +include $(topsrcdir)/config/rules.mk + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/genstubs.pl b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/genstubs.pl new file mode 100755 index 00000000..b8962930 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/genstubs.pl @@ -0,0 +1,78 @@ +#!/usr/local/bin/perl + +# This is used to generate stub entry points. We generate a file to +# be included in the declaraion and a file to be used for expanding macros +# to represent the implementation of the stubs. + +# +# if "$entry_count" is ever changed and the .inc files regenerated then +# the following issues need to be addressed: +# +# 1) Alpha NT has a .def file that lists exports by symbol. It will need +# updating. +# 2) The current Linux ARM code has a limitation of only having 256-3 stubs +# +# more dependencies??? +# + +# 3 entries are already 'used' by the 3 methods of nsISupports. +# 3+247+5=255 This should get us in under the Linux ARM limitation +$entry_count = 247; +$sentinel_count = 5; + +$decl_name = "xptcstubsdecl.inc"; +$def_name = "xptcstubsdef.inc"; + +## +## Write the declarations include file +## + +die "Can't open $decl_name" if !open(OUTFILE, ">$decl_name"); + +print OUTFILE "/* generated file - DO NOT EDIT */\n\n"; +print OUTFILE "/* includes ",$entry_count," stub entries, and ", + $sentinel_count," sentinel entries */\n\n"; +print OUTFILE "/*\n"; +print OUTFILE "* declarations of normal stubs...\n"; +print OUTFILE "* 0 is QueryInterface\n"; +print OUTFILE "* 1 is AddRef\n"; +print OUTFILE "* 2 is Release\n"; +print OUTFILE "*/\n"; +print OUTFILE "#if !defined(__ia64) || (!defined(__hpux) && !defined(__linux__))\n"; +for($i = 0; $i < $entry_count; $i++) { + print OUTFILE "NS_IMETHOD Stub",$i+3,"();\n"; +} +print OUTFILE "#else\n"; +for($i = 0; $i < $entry_count; $i++) { + print OUTFILE "NS_IMETHOD Stub",$i+3,"(PRUint64,\n"; + print OUTFILE " PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64);\n"; + +} +print OUTFILE "#endif\n"; + +print OUTFILE "\n/* declarations of sentinel stubs */\n"; + +for($i = 0; $i < $sentinel_count; $i++) { + print OUTFILE "NS_IMETHOD Sentinel",$i,"();\n"; +} +close(OUTFILE); + + +## +## Write the definitions include file. This assumes a macro will be used to +## expand the entries written... +## + +die "Can't open $def_name" if !open(OUTFILE, ">$def_name"); + +print OUTFILE "/* generated file - DO NOT EDIT */\n\n"; +print OUTFILE "/* includes ",$entry_count," stub entries, and ", + $sentinel_count," sentinel entries */\n\n"; + +for($i = 0; $i < $entry_count; $i++) { + print OUTFILE "STUB_ENTRY(",$i+3,")\n"; +} + +for($i = 0; $i < $sentinel_count; $i++) { + print OUTFILE "SENTINEL_ENTRY(",$i,")\n"; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/xptcall.h b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/xptcall.h new file mode 100644 index 00000000..153a047e --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/xptcall.h @@ -0,0 +1,271 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Public declarations for xptcall. */ + +#ifndef xptcall_h___ +#define xptcall_h___ + +#include "prtypes.h" +#include "nscore.h" +#include "nsISupports.h" +#include "xpt_struct.h" +#include "xptinfo.h" +#include "nsIInterfaceInfo.h" + +#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP +#define XPTC_InvokeByIndex VBoxNsxpXPTC_InvokeByIndex +#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */ + +/***************************************************************************/ +/* + * The linkage of XPTC API functions differs depending on whether the file is + * used within the XPTC library or not. Any source file within the XPTC + * library should define EXPORT_XPTC_API whereas any client of the library + * should not. + */ +#ifdef EXPORT_XPTC_API +#define XPTC_PUBLIC_API(t) PR_IMPLEMENT(t) +#define XPTC_PUBLIC_DATA(t) PR_IMPLEMENT_DATA(t) +#if defined(_WIN32) +# define XPTC_EXPORT __declspec(dllexport) +#elif defined(XP_OS2) && defined(__declspec) +# define XPTC_EXPORT __declspec(dllexport) +#elif defined(XP_OS2_VACPP) +# define XPTC_EXPORT extern +#else +# ifdef VBOX_HAVE_VISIBILITY_HIDDEN +# define XPTC_EXPORT __attribute__((visibility("default"))) +# else +# define XPTC_EXPORT +# endif +#endif +#else +#if defined(_WIN32) +# define XPTC_PUBLIC_API(t) __declspec(dllimport) t +# define XPTC_PUBLIC_DATA(t) __declspec(dllimport) t +# define XPTC_EXPORT __declspec(dllimport) +#elif defined(XP_OS2) && defined(__declspec) +# define XPTC_PUBLIC_API(t) __declspec(dllimport) t +# define XPTC_PUBLIC_DATA(t) __declspec(dllimport) t +# define XPTC_EXPORT __declspec(dllimport) +#elif defined(XP_OS2_VACPP) +# define XPTC_PUBLIC_API(t) extern t +# define XPTC_PUBLIC_DATA(t) extern t +# define XPTC_EXPORT extern +#else +# define XPTC_PUBLIC_API(t) PR_IMPLEMENT(t) +# define XPTC_PUBLIC_DATA(t) t +# define XPTC_EXPORT +#endif +#endif +#define XPTC_FRIEND_API(t) XPTC_PUBLIC_API(t) +#define XPTC_FRIEND_DATA(t) XPTC_PUBLIC_DATA(t) +/***************************************************************************/ + +struct nsXPTCMiniVariant +{ +// No ctors or dtors so that we can use arrays of these on the stack +// with no penalty. + union + { + PRInt8 i8; + PRInt16 i16; + PRInt32 i32; + PRInt64 i64; + PRUint8 u8; + PRUint16 u16; + PRUint32 u32; + PRUint64 u64; + float f; + double d; + PRBool b; + char c; + PRUnichar wc; + void* p; + } val; +}; + +struct nsXPTCVariant : public nsXPTCMiniVariant +{ +// No ctors or dtors so that we can use arrays of these on the stack +// with no penalty. + + // inherits 'val' here + void* ptr; + nsXPTType type; + PRUint8 flags; + + enum + { + // these are bitflags! + PTR_IS_DATA = 0x1, // ptr points to 'real' data in val + VAL_IS_ALLOCD = 0x2, // val.p holds alloc'd ptr that must be freed + VAL_IS_IFACE = 0x4, // val.p holds interface ptr that must be released + VAL_IS_ARRAY = 0x8, // val.p holds a pointer to an array needing cleanup + VAL_IS_DOMSTR = 0x10, // val.p holds a pointer to domstring needing cleanup + VAL_IS_UTF8STR = 0x20, // val.p holds a pointer to utf8string needing cleanup + VAL_IS_CSTR = 0x40 // val.p holds a pointer to cstring needing cleanup + }; + + /* VBox: Added to prevent -Wclass-memaccess warnings (nsXPTType has a constructor) in python/src/VariantUtils.cpp */ + nsXPTCVariant() : ptr(NULL), flags(0) + { + val.p = NULL; + type.flags = 0; /* stupid nsXPTType constructor only do random bytes (documented) */ + } + + void ClearFlags() {flags = 0;} + void SetPtrIsData() {flags |= PTR_IS_DATA;} + void SetValIsAllocated() {flags |= VAL_IS_ALLOCD;} + void SetValIsInterface() {flags |= VAL_IS_IFACE;} + void SetValIsArray() {flags |= VAL_IS_ARRAY;} + void SetValIsDOMString() {flags |= VAL_IS_DOMSTR;} + void SetValIsUTF8String() {flags |= VAL_IS_UTF8STR;} + void SetValIsCString() {flags |= VAL_IS_CSTR;} + + PRBool IsPtrData() const {return 0 != (flags & PTR_IS_DATA);} + PRBool IsValAllocated() const {return 0 != (flags & VAL_IS_ALLOCD);} + PRBool IsValInterface() const {return 0 != (flags & VAL_IS_IFACE);} + PRBool IsValArray() const {return 0 != (flags & VAL_IS_ARRAY);} + PRBool IsValDOMString() const {return 0 != (flags & VAL_IS_DOMSTR);} + PRBool IsValUTF8String() const {return 0 != (flags & VAL_IS_UTF8STR);} + PRBool IsValCString() const {return 0 != (flags & VAL_IS_CSTR);} +#ifdef VBOX + PRBool MustFreeVal() const {return 0 != (flags & ( VAL_IS_ALLOCD + | VAL_IS_IFACE + | VAL_IS_DOMSTR + | VAL_IS_UTF8STR + | VAL_IS_CSTR)); } +#endif + + void Init(const nsXPTCMiniVariant& mv, const nsXPTType& t, PRUint8 f) + { + type = t; + flags = f; + + if(f & PTR_IS_DATA) + { + ptr = mv.val.p; + val.p = nsnull; + } + else + { + ptr = nsnull; + switch(t.TagPart()) { + case nsXPTType::T_I8: val.i8 = mv.val.i8; break; + case nsXPTType::T_I16: val.i16 = mv.val.i16; break; + case nsXPTType::T_I32: val.i32 = mv.val.i32; break; + case nsXPTType::T_I64: val.i64 = mv.val.i64; break; + case nsXPTType::T_U8: val.u8 = mv.val.u8; break; + case nsXPTType::T_U16: val.u16 = mv.val.u16; break; + case nsXPTType::T_U32: val.u32 = mv.val.u32; break; + case nsXPTType::T_U64: val.u64 = mv.val.u64; break; + case nsXPTType::T_FLOAT: val.f = mv.val.f; break; + case nsXPTType::T_DOUBLE: val.d = mv.val.d; break; + case nsXPTType::T_BOOL: val.b = mv.val.b; break; + case nsXPTType::T_CHAR: val.c = mv.val.c; break; + case nsXPTType::T_WCHAR: val.wc = mv.val.wc; break; + case nsXPTType::T_VOID: /* fall through */ + case nsXPTType::T_IID: /* fall through */ + case nsXPTType::T_DOMSTRING: /* fall through */ + case nsXPTType::T_CHAR_STR: /* fall through */ + case nsXPTType::T_WCHAR_STR: /* fall through */ + case nsXPTType::T_INTERFACE: /* fall through */ + case nsXPTType::T_INTERFACE_IS: /* fall through */ + case nsXPTType::T_ARRAY: /* fall through */ + case nsXPTType::T_PSTRING_SIZE_IS: /* fall through */ + case nsXPTType::T_PWSTRING_SIZE_IS: /* fall through */ + case nsXPTType::T_UTF8STRING: /* fall through */ + case nsXPTType::T_CSTRING: /* fall through */ + default: val.p = mv.val.p; break; + } + } + } +}; + +/***************************************************************************/ + +#undef IMETHOD_VISIBILITY +#define IMETHOD_VISIBILITY NS_VISIBILITY_DEFAULT + +class XPTC_EXPORT nsXPTCStubBase : public nsISupports +{ +public: + // We are going to implement this to force the compiler to generate a + // vtbl for this class. Since this is overridden in the inheriting class + // we expect it to never be called. + // *This is needed by the Irix implementation.* + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); + + // Implement dummy constructor, destructor to workaround Solaris gcc 4.8.2 + // linking issue (see @bugref{5838}). + nsXPTCStubBase() {} + ~nsXPTCStubBase() {} + + // Include generated vtbl stub declarations. + // These are virtual and *also* implemented by this class.. +#include "xptcstubsdecl.inc" + + // The following methods must be provided by inheritor of this class. + + // return a refcounted pointer to the InterfaceInfo for this object + // NOTE: on some platforms this MUST not fail or we crash! + NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info) = 0; + + // call this method and return result + NS_IMETHOD CallMethod(PRUint16 methodIndex, + const nsXPTMethodInfo* info, + nsXPTCMiniVariant* params) = 0; +}; + +#undef IMETHOD_VISIBILITY +#define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN + +PR_BEGIN_EXTERN_C + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +// Used to force linking of these obj for the static library into the dll +extern void xptc_dummy(); +extern void xptc_dummy2(); + +PR_END_EXTERN_C + +#endif /* xptcall_h___ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/xptcstubsdecl.inc b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/xptcstubsdecl.inc new file mode 100644 index 00000000..99116d68 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/xptcstubsdecl.inc @@ -0,0 +1,761 @@ +/* generated file - DO NOT EDIT */ + +/* includes 247 stub entries, and 5 sentinel entries */ + +/* +* declarations of normal stubs... +* 0 is QueryInterface +* 1 is AddRef +* 2 is Release +*/ +#if !defined(__ia64) || (!defined(__hpux) && !defined(__linux__)) +NS_IMETHOD Stub3(); +NS_IMETHOD Stub4(); +NS_IMETHOD Stub5(); +NS_IMETHOD Stub6(); +NS_IMETHOD Stub7(); +NS_IMETHOD Stub8(); +NS_IMETHOD Stub9(); +NS_IMETHOD Stub10(); +NS_IMETHOD Stub11(); +NS_IMETHOD Stub12(); +NS_IMETHOD Stub13(); +NS_IMETHOD Stub14(); +NS_IMETHOD Stub15(); +NS_IMETHOD Stub16(); +NS_IMETHOD Stub17(); +NS_IMETHOD Stub18(); +NS_IMETHOD Stub19(); +NS_IMETHOD Stub20(); +NS_IMETHOD Stub21(); +NS_IMETHOD Stub22(); +NS_IMETHOD Stub23(); +NS_IMETHOD Stub24(); +NS_IMETHOD Stub25(); +NS_IMETHOD Stub26(); +NS_IMETHOD Stub27(); +NS_IMETHOD Stub28(); +NS_IMETHOD Stub29(); +NS_IMETHOD Stub30(); +NS_IMETHOD Stub31(); +NS_IMETHOD Stub32(); +NS_IMETHOD Stub33(); +NS_IMETHOD Stub34(); +NS_IMETHOD Stub35(); +NS_IMETHOD Stub36(); +NS_IMETHOD Stub37(); +NS_IMETHOD Stub38(); +NS_IMETHOD Stub39(); +NS_IMETHOD Stub40(); +NS_IMETHOD Stub41(); +NS_IMETHOD Stub42(); +NS_IMETHOD Stub43(); +NS_IMETHOD Stub44(); +NS_IMETHOD Stub45(); +NS_IMETHOD Stub46(); +NS_IMETHOD Stub47(); +NS_IMETHOD Stub48(); +NS_IMETHOD Stub49(); +NS_IMETHOD Stub50(); +NS_IMETHOD Stub51(); +NS_IMETHOD Stub52(); +NS_IMETHOD Stub53(); +NS_IMETHOD Stub54(); +NS_IMETHOD Stub55(); +NS_IMETHOD Stub56(); +NS_IMETHOD Stub57(); +NS_IMETHOD Stub58(); +NS_IMETHOD Stub59(); +NS_IMETHOD Stub60(); +NS_IMETHOD Stub61(); +NS_IMETHOD Stub62(); +NS_IMETHOD Stub63(); +NS_IMETHOD Stub64(); +NS_IMETHOD Stub65(); +NS_IMETHOD Stub66(); +NS_IMETHOD Stub67(); +NS_IMETHOD Stub68(); +NS_IMETHOD Stub69(); +NS_IMETHOD Stub70(); +NS_IMETHOD Stub71(); +NS_IMETHOD Stub72(); +NS_IMETHOD Stub73(); +NS_IMETHOD Stub74(); +NS_IMETHOD Stub75(); +NS_IMETHOD Stub76(); +NS_IMETHOD Stub77(); +NS_IMETHOD Stub78(); +NS_IMETHOD Stub79(); +NS_IMETHOD Stub80(); +NS_IMETHOD Stub81(); +NS_IMETHOD Stub82(); +NS_IMETHOD Stub83(); +NS_IMETHOD Stub84(); +NS_IMETHOD Stub85(); +NS_IMETHOD Stub86(); +NS_IMETHOD Stub87(); +NS_IMETHOD Stub88(); +NS_IMETHOD Stub89(); +NS_IMETHOD Stub90(); +NS_IMETHOD Stub91(); +NS_IMETHOD Stub92(); +NS_IMETHOD Stub93(); +NS_IMETHOD Stub94(); +NS_IMETHOD Stub95(); +NS_IMETHOD Stub96(); +NS_IMETHOD Stub97(); +NS_IMETHOD Stub98(); +NS_IMETHOD Stub99(); +NS_IMETHOD Stub100(); +NS_IMETHOD Stub101(); +NS_IMETHOD Stub102(); +NS_IMETHOD Stub103(); +NS_IMETHOD Stub104(); +NS_IMETHOD Stub105(); +NS_IMETHOD Stub106(); +NS_IMETHOD Stub107(); +NS_IMETHOD Stub108(); +NS_IMETHOD Stub109(); +NS_IMETHOD Stub110(); +NS_IMETHOD Stub111(); +NS_IMETHOD Stub112(); +NS_IMETHOD Stub113(); +NS_IMETHOD Stub114(); +NS_IMETHOD Stub115(); +NS_IMETHOD Stub116(); +NS_IMETHOD Stub117(); +NS_IMETHOD Stub118(); +NS_IMETHOD Stub119(); +NS_IMETHOD Stub120(); +NS_IMETHOD Stub121(); +NS_IMETHOD Stub122(); +NS_IMETHOD Stub123(); +NS_IMETHOD Stub124(); +NS_IMETHOD Stub125(); +NS_IMETHOD Stub126(); +NS_IMETHOD Stub127(); +NS_IMETHOD Stub128(); +NS_IMETHOD Stub129(); +NS_IMETHOD Stub130(); +NS_IMETHOD Stub131(); +NS_IMETHOD Stub132(); +NS_IMETHOD Stub133(); +NS_IMETHOD Stub134(); +NS_IMETHOD Stub135(); +NS_IMETHOD Stub136(); +NS_IMETHOD Stub137(); +NS_IMETHOD Stub138(); +NS_IMETHOD Stub139(); +NS_IMETHOD Stub140(); +NS_IMETHOD Stub141(); +NS_IMETHOD Stub142(); +NS_IMETHOD Stub143(); +NS_IMETHOD Stub144(); +NS_IMETHOD Stub145(); +NS_IMETHOD Stub146(); +NS_IMETHOD Stub147(); +NS_IMETHOD Stub148(); +NS_IMETHOD Stub149(); +NS_IMETHOD Stub150(); +NS_IMETHOD Stub151(); +NS_IMETHOD Stub152(); +NS_IMETHOD Stub153(); +NS_IMETHOD Stub154(); +NS_IMETHOD Stub155(); +NS_IMETHOD Stub156(); +NS_IMETHOD Stub157(); +NS_IMETHOD Stub158(); +NS_IMETHOD Stub159(); +NS_IMETHOD Stub160(); +NS_IMETHOD Stub161(); +NS_IMETHOD Stub162(); +NS_IMETHOD Stub163(); +NS_IMETHOD Stub164(); +NS_IMETHOD Stub165(); +NS_IMETHOD Stub166(); +NS_IMETHOD Stub167(); +NS_IMETHOD Stub168(); +NS_IMETHOD Stub169(); +NS_IMETHOD Stub170(); +NS_IMETHOD Stub171(); +NS_IMETHOD Stub172(); +NS_IMETHOD Stub173(); +NS_IMETHOD Stub174(); +NS_IMETHOD Stub175(); +NS_IMETHOD Stub176(); +NS_IMETHOD Stub177(); +NS_IMETHOD Stub178(); +NS_IMETHOD Stub179(); +NS_IMETHOD Stub180(); +NS_IMETHOD Stub181(); +NS_IMETHOD Stub182(); +NS_IMETHOD Stub183(); +NS_IMETHOD Stub184(); +NS_IMETHOD Stub185(); +NS_IMETHOD Stub186(); +NS_IMETHOD Stub187(); +NS_IMETHOD Stub188(); +NS_IMETHOD Stub189(); +NS_IMETHOD Stub190(); +NS_IMETHOD Stub191(); +NS_IMETHOD Stub192(); +NS_IMETHOD Stub193(); +NS_IMETHOD Stub194(); +NS_IMETHOD Stub195(); +NS_IMETHOD Stub196(); +NS_IMETHOD Stub197(); +NS_IMETHOD Stub198(); +NS_IMETHOD Stub199(); +NS_IMETHOD Stub200(); +NS_IMETHOD Stub201(); +NS_IMETHOD Stub202(); +NS_IMETHOD Stub203(); +NS_IMETHOD Stub204(); +NS_IMETHOD Stub205(); +NS_IMETHOD Stub206(); +NS_IMETHOD Stub207(); +NS_IMETHOD Stub208(); +NS_IMETHOD Stub209(); +NS_IMETHOD Stub210(); +NS_IMETHOD Stub211(); +NS_IMETHOD Stub212(); +NS_IMETHOD Stub213(); +NS_IMETHOD Stub214(); +NS_IMETHOD Stub215(); +NS_IMETHOD Stub216(); +NS_IMETHOD Stub217(); +NS_IMETHOD Stub218(); +NS_IMETHOD Stub219(); +NS_IMETHOD Stub220(); +NS_IMETHOD Stub221(); +NS_IMETHOD Stub222(); +NS_IMETHOD Stub223(); +NS_IMETHOD Stub224(); +NS_IMETHOD Stub225(); +NS_IMETHOD Stub226(); +NS_IMETHOD Stub227(); +NS_IMETHOD Stub228(); +NS_IMETHOD Stub229(); +NS_IMETHOD Stub230(); +NS_IMETHOD Stub231(); +NS_IMETHOD Stub232(); +NS_IMETHOD Stub233(); +NS_IMETHOD Stub234(); +NS_IMETHOD Stub235(); +NS_IMETHOD Stub236(); +NS_IMETHOD Stub237(); +NS_IMETHOD Stub238(); +NS_IMETHOD Stub239(); +NS_IMETHOD Stub240(); +NS_IMETHOD Stub241(); +NS_IMETHOD Stub242(); +NS_IMETHOD Stub243(); +NS_IMETHOD Stub244(); +NS_IMETHOD Stub245(); +NS_IMETHOD Stub246(); +NS_IMETHOD Stub247(); +NS_IMETHOD Stub248(); +NS_IMETHOD Stub249(); +#else +NS_IMETHOD Stub3(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub4(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub5(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub6(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub7(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub8(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub9(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub10(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub11(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub12(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub13(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub14(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub15(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub16(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub17(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub18(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub19(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub20(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub21(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub22(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub23(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub24(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub25(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub26(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub27(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub28(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub29(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub30(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub31(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub32(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub33(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub34(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub35(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub36(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub37(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub38(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub39(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub40(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub41(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub42(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub43(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub44(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub45(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub46(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub47(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub48(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub49(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub50(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub51(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub52(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub53(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub54(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub55(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub56(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub57(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub58(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub59(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub60(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub61(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub62(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub63(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub64(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub65(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub66(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub67(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub68(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub69(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub70(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub71(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub72(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub73(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub74(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub75(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub76(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub77(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub78(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub79(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub80(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub81(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub82(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub83(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub84(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub85(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub86(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub87(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub88(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub89(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub90(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub91(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub92(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub93(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub94(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub95(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub96(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub97(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub98(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub99(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub100(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub101(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub102(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub103(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub104(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub105(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub106(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub107(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub108(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub109(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub110(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub111(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub112(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub113(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub114(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub115(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub116(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub117(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub118(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub119(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub120(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub121(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub122(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub123(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub124(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub125(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub126(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub127(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub128(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub129(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub130(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub131(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub132(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub133(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub134(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub135(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub136(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub137(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub138(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub139(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub140(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub141(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub142(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub143(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub144(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub145(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub146(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub147(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub148(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub149(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub150(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub151(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub152(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub153(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub154(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub155(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub156(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub157(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub158(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub159(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub160(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub161(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub162(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub163(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub164(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub165(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub166(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub167(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub168(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub169(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub170(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub171(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub172(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub173(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub174(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub175(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub176(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub177(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub178(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub179(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub180(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub181(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub182(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub183(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub184(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub185(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub186(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub187(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub188(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub189(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub190(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub191(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub192(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub193(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub194(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub195(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub196(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub197(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub198(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub199(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub200(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub201(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub202(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub203(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub204(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub205(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub206(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub207(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub208(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub209(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub210(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub211(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub212(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub213(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub214(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub215(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub216(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub217(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub218(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub219(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub220(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub221(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub222(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub223(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub224(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub225(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub226(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub227(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub228(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub229(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub230(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub231(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub232(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub233(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub234(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub235(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub236(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub237(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub238(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub239(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub240(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub241(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub242(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub243(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub244(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub245(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub246(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub247(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub248(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +NS_IMETHOD Stub249(PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); +#endif + +/* declarations of sentinel stubs */ +NS_IMETHOD Sentinel0(); +NS_IMETHOD Sentinel1(); +NS_IMETHOD Sentinel2(); +NS_IMETHOD Sentinel3(); +NS_IMETHOD Sentinel4(); diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/xptcstubsdef.inc b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/xptcstubsdef.inc new file mode 100644 index 00000000..780e2f52 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/public/xptcstubsdef.inc @@ -0,0 +1,256 @@ +/* generated file - DO NOT EDIT */ + +/* includes 247 stub entries, and 5 sentinel entries */ + +STUB_ENTRY(3) +STUB_ENTRY(4) +STUB_ENTRY(5) +STUB_ENTRY(6) +STUB_ENTRY(7) +STUB_ENTRY(8) +STUB_ENTRY(9) +STUB_ENTRY(10) +STUB_ENTRY(11) +STUB_ENTRY(12) +STUB_ENTRY(13) +STUB_ENTRY(14) +STUB_ENTRY(15) +STUB_ENTRY(16) +STUB_ENTRY(17) +STUB_ENTRY(18) +STUB_ENTRY(19) +STUB_ENTRY(20) +STUB_ENTRY(21) +STUB_ENTRY(22) +STUB_ENTRY(23) +STUB_ENTRY(24) +STUB_ENTRY(25) +STUB_ENTRY(26) +STUB_ENTRY(27) +STUB_ENTRY(28) +STUB_ENTRY(29) +STUB_ENTRY(30) +STUB_ENTRY(31) +STUB_ENTRY(32) +STUB_ENTRY(33) +STUB_ENTRY(34) +STUB_ENTRY(35) +STUB_ENTRY(36) +STUB_ENTRY(37) +STUB_ENTRY(38) +STUB_ENTRY(39) +STUB_ENTRY(40) +STUB_ENTRY(41) +STUB_ENTRY(42) +STUB_ENTRY(43) +STUB_ENTRY(44) +STUB_ENTRY(45) +STUB_ENTRY(46) +STUB_ENTRY(47) +STUB_ENTRY(48) +STUB_ENTRY(49) +STUB_ENTRY(50) +STUB_ENTRY(51) +STUB_ENTRY(52) +STUB_ENTRY(53) +STUB_ENTRY(54) +STUB_ENTRY(55) +STUB_ENTRY(56) +STUB_ENTRY(57) +STUB_ENTRY(58) +STUB_ENTRY(59) +STUB_ENTRY(60) +STUB_ENTRY(61) +STUB_ENTRY(62) +STUB_ENTRY(63) +STUB_ENTRY(64) +STUB_ENTRY(65) +STUB_ENTRY(66) +STUB_ENTRY(67) +STUB_ENTRY(68) +STUB_ENTRY(69) +STUB_ENTRY(70) +STUB_ENTRY(71) +STUB_ENTRY(72) +STUB_ENTRY(73) +STUB_ENTRY(74) +STUB_ENTRY(75) +STUB_ENTRY(76) +STUB_ENTRY(77) +STUB_ENTRY(78) +STUB_ENTRY(79) +STUB_ENTRY(80) +STUB_ENTRY(81) +STUB_ENTRY(82) +STUB_ENTRY(83) +STUB_ENTRY(84) +STUB_ENTRY(85) +STUB_ENTRY(86) +STUB_ENTRY(87) +STUB_ENTRY(88) +STUB_ENTRY(89) +STUB_ENTRY(90) +STUB_ENTRY(91) +STUB_ENTRY(92) +STUB_ENTRY(93) +STUB_ENTRY(94) +STUB_ENTRY(95) +STUB_ENTRY(96) +STUB_ENTRY(97) +STUB_ENTRY(98) +STUB_ENTRY(99) +STUB_ENTRY(100) +STUB_ENTRY(101) +STUB_ENTRY(102) +STUB_ENTRY(103) +STUB_ENTRY(104) +STUB_ENTRY(105) +STUB_ENTRY(106) +STUB_ENTRY(107) +STUB_ENTRY(108) +STUB_ENTRY(109) +STUB_ENTRY(110) +STUB_ENTRY(111) +STUB_ENTRY(112) +STUB_ENTRY(113) +STUB_ENTRY(114) +STUB_ENTRY(115) +STUB_ENTRY(116) +STUB_ENTRY(117) +STUB_ENTRY(118) +STUB_ENTRY(119) +STUB_ENTRY(120) +STUB_ENTRY(121) +STUB_ENTRY(122) +STUB_ENTRY(123) +STUB_ENTRY(124) +STUB_ENTRY(125) +STUB_ENTRY(126) +STUB_ENTRY(127) +STUB_ENTRY(128) +STUB_ENTRY(129) +STUB_ENTRY(130) +STUB_ENTRY(131) +STUB_ENTRY(132) +STUB_ENTRY(133) +STUB_ENTRY(134) +STUB_ENTRY(135) +STUB_ENTRY(136) +STUB_ENTRY(137) +STUB_ENTRY(138) +STUB_ENTRY(139) +STUB_ENTRY(140) +STUB_ENTRY(141) +STUB_ENTRY(142) +STUB_ENTRY(143) +STUB_ENTRY(144) +STUB_ENTRY(145) +STUB_ENTRY(146) +STUB_ENTRY(147) +STUB_ENTRY(148) +STUB_ENTRY(149) +STUB_ENTRY(150) +STUB_ENTRY(151) +STUB_ENTRY(152) +STUB_ENTRY(153) +STUB_ENTRY(154) +STUB_ENTRY(155) +STUB_ENTRY(156) +STUB_ENTRY(157) +STUB_ENTRY(158) +STUB_ENTRY(159) +STUB_ENTRY(160) +STUB_ENTRY(161) +STUB_ENTRY(162) +STUB_ENTRY(163) +STUB_ENTRY(164) +STUB_ENTRY(165) +STUB_ENTRY(166) +STUB_ENTRY(167) +STUB_ENTRY(168) +STUB_ENTRY(169) +STUB_ENTRY(170) +STUB_ENTRY(171) +STUB_ENTRY(172) +STUB_ENTRY(173) +STUB_ENTRY(174) +STUB_ENTRY(175) +STUB_ENTRY(176) +STUB_ENTRY(177) +STUB_ENTRY(178) +STUB_ENTRY(179) +STUB_ENTRY(180) +STUB_ENTRY(181) +STUB_ENTRY(182) +STUB_ENTRY(183) +STUB_ENTRY(184) +STUB_ENTRY(185) +STUB_ENTRY(186) +STUB_ENTRY(187) +STUB_ENTRY(188) +STUB_ENTRY(189) +STUB_ENTRY(190) +STUB_ENTRY(191) +STUB_ENTRY(192) +STUB_ENTRY(193) +STUB_ENTRY(194) +STUB_ENTRY(195) +STUB_ENTRY(196) +STUB_ENTRY(197) +STUB_ENTRY(198) +STUB_ENTRY(199) +STUB_ENTRY(200) +STUB_ENTRY(201) +STUB_ENTRY(202) +STUB_ENTRY(203) +STUB_ENTRY(204) +STUB_ENTRY(205) +STUB_ENTRY(206) +STUB_ENTRY(207) +STUB_ENTRY(208) +STUB_ENTRY(209) +STUB_ENTRY(210) +STUB_ENTRY(211) +STUB_ENTRY(212) +STUB_ENTRY(213) +STUB_ENTRY(214) +STUB_ENTRY(215) +STUB_ENTRY(216) +STUB_ENTRY(217) +STUB_ENTRY(218) +STUB_ENTRY(219) +STUB_ENTRY(220) +STUB_ENTRY(221) +STUB_ENTRY(222) +STUB_ENTRY(223) +STUB_ENTRY(224) +STUB_ENTRY(225) +STUB_ENTRY(226) +STUB_ENTRY(227) +STUB_ENTRY(228) +STUB_ENTRY(229) +STUB_ENTRY(230) +STUB_ENTRY(231) +STUB_ENTRY(232) +STUB_ENTRY(233) +STUB_ENTRY(234) +STUB_ENTRY(235) +STUB_ENTRY(236) +STUB_ENTRY(237) +STUB_ENTRY(238) +STUB_ENTRY(239) +STUB_ENTRY(240) +STUB_ENTRY(241) +STUB_ENTRY(242) +STUB_ENTRY(243) +STUB_ENTRY(244) +STUB_ENTRY(245) +STUB_ENTRY(246) +STUB_ENTRY(247) +STUB_ENTRY(248) +STUB_ENTRY(249) +SENTINEL_ENTRY(0) +SENTINEL_ENTRY(1) +SENTINEL_ENTRY(2) +SENTINEL_ENTRY(3) +SENTINEL_ENTRY(4) diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/Makefile.in new file mode 100644 index 00000000..987fc505 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/Makefile.in @@ -0,0 +1,62 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +LIBRARY_NAME = xptcall + + +DIRS = md + +CPPSRCS = xptcall.cpp + +# we don't want the shared lib, but we want to force the creation of a static lib. +FORCE_STATIC_LIB = 1 + +# Force use of PIC +FORCE_USE_PIC = 1 + +include $(topsrcdir)/config/rules.mk + +DEFINES += -DEXPORT_XPTC_API -D_IMPL_NS_COM -D_IMPL_NS_BASE + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/Makefile.kup b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/Makefile.kup new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/Makefile.kup diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/Makefile.in new file mode 100644 index 00000000..dd70cabf --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/Makefile.in @@ -0,0 +1,56 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +ifeq ($(MOZ_WIDGET_TOOLKIT),os2) +DIRS = os2 +else +ifeq ($(MOZ_WIDGET_TOOLKIT),windows) +DIRS = win32 +else +DIRS = unix +endif +endif + +include $(topsrcdir)/config/rules.mk + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/Makefile.kup b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/Makefile.kup new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/Makefile.kup diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcinvoke_mac.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcinvoke_mac.cpp new file mode 100644 index 00000000..29343c08 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcinvoke_mac.cpp @@ -0,0 +1,148 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +#ifndef XP_MAC +#error "This code is for Macintosh only" +#endif + +extern "C" uint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 result = 0; + for(PRUint32 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; + } + } + return result; +} + +extern "C" void +invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s, double *fprData) +{ + PRUint32 fpCount = 0; + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : *((PRInt32*) d) = s->val.i8; break; + case nsXPTType::T_I16 : *((PRInt32*) d) = s->val.i16; break; + case nsXPTType::T_I32 : *((PRInt32*) d) = s->val.i32; break; + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U8 : *((PRUint32*) d) = s->val.u8; break; + case nsXPTType::T_U16 : *((PRUint32*)d) = s->val.u16; break; + case nsXPTType::T_U32 : *((PRUint32*)d) = s->val.u32; break; + case nsXPTType::T_U64 : *((PRUint64*)d) = s->val.u64; d++; break; + case nsXPTType::T_FLOAT : *((float*) d) = s->val.f; + if (fpCount < 13) + fprData[fpCount++] = s->val.f; + break; + case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; + if (fpCount < 13) + fprData[fpCount++] = s->val.d; + break; + case nsXPTType::T_BOOL : *((PRBool*) d) = s->val.b; break; + case nsXPTType::T_CHAR : *((PRInt32*) d) = s->val.c; break; + case nsXPTType::T_WCHAR : *((PRUint32*) d) = s->val.wc; break; + default: + // all the others are plain pointer types + *((void**)d) = s->val.p; + break; + } + } +} + +#pragma export on + +extern "C" nsresult _XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +extern "C" +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + return _XPTC_InvokeByIndex(that, methodIndex, paramCount, params); +} + +#pragma export off diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcinvoke_mac.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcinvoke_mac.s new file mode 100644 index 00000000..47544dd3 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcinvoke_mac.s @@ -0,0 +1,128 @@ + # + # -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + # + # The contents of this file are subject to the Netscape Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/NPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is mozilla.org code. + # + # The Initial Developer of the Original Code is Netscape + # Communications Corporation. Portions created by Netscape are + # Copyright (C) 1999 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): + # + + csect CODE{PR} +# +# XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +# PRUint32 paramCount, nsXPTCVariant* params) +# + + import .invoke_count_words + import .invoke_copy_to_stack + import .__ptr_glue + +._XPTC_InvokeByIndex: + mflr r0 + stw r31,-4(sp) +# +# save off the incoming values in the caller's parameter area +# + stw r3,24(sp) # that + stw r4,28(sp) # methodIndex + stw r5,32(sp) # paramCount + stw r6,36(sp) # params + stw r0,8(sp) + stwu sp,-144(sp) # = 24 for linkage area, 8 * 13 for fprData area, 8 for saved registers, + # 8 to keep stack 16-byte aligned. + +# set up for and call 'invoke_count_words' to get new stack size +# + mr r3,r5 + mr r4,r6 + bl .invoke_count_words + nop + +# prepare args for 'invoke_copy_to_stack' call +# + lwz r4,176(sp) # paramCount + lwz r5,180(sp) # params +# addi r6,sp,128 # fprData + mr r6,sp # fprData + slwi r3,r3,2 # number of bytes of stack required + addi r3,r3,28 # linkage area + mr r31,sp # save original stack top + sub sp,sp,r3 # bump the stack + clrrwi sp,sp,4 # keep the stack 16-byte aligned. + lwz r3,0(r31) # act like real alloca, so 0(sp) always points back to + stw r3,0(sp) # previous stack frame. + addi r3,sp,28 # parameter pointer excludes linkage area size + 'this' + + bl .invoke_copy_to_stack + nop + + lfd f1,0(r31) + lfd f2,8(r31) + lfd f3,16(r31) + lfd f4,24(r31) + lfd f5,32(r31) + lfd f6,40(r31) + lfd f7,48(r31) + lfd f8,56(r31) + lfd f9,64(r31) + lfd f10,72(r31) + lfd f11,80(r31) + lfd f12,88(r31) + lfd f13,96(r31) + + lwz r3,168(r31) # that + lwz r4,0(r3) # get vTable from 'that' + lwz r5,172(r31) # methodIndex + slwi r5,r5,2 # methodIndex * 4 + addi r5,r5,8 # step over junk at start of vTable ! + lwzx r12,r5,r4 # get function pointer + + lwz r4,28(sp) + lwz r5,32(sp) + lwz r6,36(sp) + lwz r7,40(sp) + lwz r8,44(sp) + lwz r9,48(sp) + lwz r10,52(sp) + + bl .__ptr_glue + nop + + + mr sp,r31 + lwz r0,152(sp) + addi sp,sp,144 + mtlr r0 + lwz r31,-4(sp) + blr + +# traceback table. + traceback: + dc.l 0 + dc.l 0x00002040 + dc.l 0 + dc.l (traceback - ._XPTC_InvokeByIndex) # size of the code. + dc.w 20 # short length of identifier. + dc.b '._XPTC_InvokeByIndex' + + csect DATA + import TOC + export ._XPTC_InvokeByIndex + + dc.l ._XPTC_InvokeByIndex + dc.l TOC +
\ No newline at end of file diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcstubs_mac.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcstubs_mac.cpp new file mode 100644 index 00000000..3fea7d51 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcstubs_mac.cpp @@ -0,0 +1,265 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#pragma export on + +#include "xptcprivate.h" + +#if defined(XP_MAC) + +/* + For mac, the first 8 integral and the first 13 f.p. parameters arrive + in a separate chunk of data that has been loaded from the registers. The + args pointer has been set to the start of the parameters BEYOND the ones + arriving in registers +*/ +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, PRUint32 *gprData, double *fprData) +{ +#define PARAM_BUFFER_COUNT 16 +#define PARAM_GPR_COUNT 7 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* ap = args; + PRUint32 iCount = 0; + PRUint32 fpCount = 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 = (PRInt8) gprData[iCount++]; + else + dp->val.i8 = (PRInt8) *ap++; + break; + case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT) + dp->val.i16 = (PRInt16) gprData[iCount++]; + else + dp->val.i16 = (PRInt16) *ap++; + break; + case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT) + dp->val.i32 = (PRInt32) gprData[iCount++]; + else + dp->val.i32 = (PRInt32) *ap++; + break; + case nsXPTType::T_I64 : +#ifdef HAVE_LONG_LONG + PRUint64 tempu64; + if (iCount & 1) iCount++; // longlongs are aligned in odd/even register pairs, eg. r5/r6 + if ((iCount + 1) < PARAM_GPR_COUNT) + { + tempu64 = *(PRUint64*) &gprData[iCount]; + iCount += 2; + } + else + { + if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack + tempu64 = *(PRUint64*) ap; + ap += 2; + } + dp->val.i64 = (PRUint64)tempu64; +#else + if (iCount < PARAM_GPR_COUNT) + dp->val.i64.hi = (PRInt32) gprData[iCount++]; + else + dp->val.i64.hi = (PRInt32) *ap++; + if (iCount < PARAM_GPR_COUNT) + dp->val.i64.lo = (PRUint32) gprData[iCount++]; + else + dp->val.i64.lo = (PRUint32) *ap++; +#endif + break; + case nsXPTType::T_U8 : if (iCount < PARAM_GPR_COUNT) + dp->val.i8 = (PRUint8) gprData[iCount++]; + else + dp->val.i8 = (PRUint8) *ap++; + break; + case nsXPTType::T_U16 : if (iCount < PARAM_GPR_COUNT) + dp->val.i16 = (PRUint16) gprData[iCount++]; + else + dp->val.i16 = (PRUint16) *ap++; + break; + case nsXPTType::T_U32 : if (iCount < PARAM_GPR_COUNT) + dp->val.i32 = (PRUint32) gprData[iCount++]; + else + dp->val.i32 = (PRUint32) *ap++; + break; + case nsXPTType::T_U64 : +#ifdef HAVE_LONG_LONG + // PRUint64 tempu64; // declared above and still in scope + if (iCount & 1) iCount++; // longlongs are aligned in odd/even register pairs, eg. r5/r6 + if ((iCount + 1) < PARAM_GPR_COUNT) + { + tempu64 = *(PRUint64*) &gprData[iCount]; + iCount += 2; + } + else + { + if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack + tempu64 = *(PRUint64*) ap; + ap += 2; + } + dp->val.i64 = (PRUint64)tempu64; +#else + if (iCount < PARAM_GPR_COUNT) + dp->val.i64.hi = (PRUint32) gprData[iCount++]; + else + dp->val.i64.hi = (PRUint32) *ap++; + if (iCount < PARAM_GPR_COUNT) + dp->val.i64.lo = (PRUint32) gprData[iCount++]; + else + dp->val.i64.lo = (PRUint32) *ap++; +#endif + break; + case nsXPTType::T_FLOAT : if (fpCount < 13) { + dp->val.f = (float) fprData[fpCount++]; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + } + else + dp->val.f = *((float*) ap++); + break; + case nsXPTType::T_DOUBLE : if (fpCount < 13) { + dp->val.d = (double) fprData[fpCount++]; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + } + else { + dp->val.f = *((double*) ap); + ap += 2; + } + break; + case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT) + dp->val.b = (PRBool) gprData[iCount++]; + else + dp->val.b = (PRBool) *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->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" void SharedStub(); + +#define STUB_ENTRY(n) \ +asm nsresult nsXPTCStubBase::Stub##n() \ +{ \ + addi r12,r0,n; \ + b SharedStub \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + + +#include "xptcstubsdef.inc" + +#pragma export off + +#endif diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcstubs_mac.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcstubs_mac.s new file mode 100644 index 00000000..d2f7185b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/mac/xptcstubs_mac.s @@ -0,0 +1,78 @@ + # + # -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + # + # The contents of this file are subject to the Netscape Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/NPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is mozilla.org code. + # + # The Initial Developer of the Original Code is Netscape + # Communications Corporation. Portions created by Netscape are + # Copyright (C) 1999 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): + # + + csect CODE{PR} +# +# on entry SharedStub has the method selector in r12, the rest of the original +# parameters are in r3 thru r10 and f1 thru f13 +# + import .PrepareAndDispatch + +.SharedStub: + mflr r0 + stw r0,8(sp) + + stwu sp,-176(sp) # room for linkage (24), fprData (104), gprData(28) + # outgoing params to PrepareAndDispatch (20) + + stw r4,44(sp) + stw r5,48(sp) + stw r6,52(sp) + stw r7,56(sp) + stw r8,60(sp) + stw r9,64(sp) + stw r10,68(sp) + stfd f1,72(sp) + stfd f2,80(sp) + stfd f3,88(sp) + stfd f4,96(sp) + stfd f5,104(sp) + stfd f6,112(sp) + stfd f7,120(sp) + stfd f8,128(sp) + stfd f9,136(sp) + stfd f10,144(sp) + stfd f11,152(sp) + stfd f12,156(sp) + stfd f13,164(sp) + + addi r6,sp,44 # gprData + addi r7,sp,72 # fprData + # r3 has the 'self' pointer already + mr r4,r12 # methodIndex selector + addi r5,sp,232 # pointer to callers args area, beyond r3-r10 mapped range + + bl .PrepareAndDispatch + nop + + lwz r0,184(sp) + addi sp,sp,176 + mtlr r0 + blr + + csect DATA + import TOC + export .SharedStub + + dc.l .SharedStub + dc.l TOC diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/Makefile.in new file mode 100644 index 00000000..cfd57c83 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/Makefile.in @@ -0,0 +1,72 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +LIBRARY_NAME = xptcmd + +ifdef GNU_CXX +CPPSRCS = \ + ../unix/xptcinvoke_gcc_x86_unix.cpp \ + ../unix/xptcstubs_gcc_x86_unix.cpp \ + $(NULL) +LOCAL_INCLUDES = -I$(srcdir)/../unix +DEFINES += -DMOZ_NEED_LEADING_UNDERSCORE +else +CPPSRCS = xptcstubs_os2.cpp +ASFILES = xptcinvoke_vacpp.asm xptcstubs_vacpp.asm +endif + +# Force use of PIC +FORCE_USE_PIC = 1 + +include $(topsrcdir)/config/config.mk + +# we don't want the shared lib, but we want to force the creation of a static lib. +FORCE_STATIC_LIB = 1 + +include $(topsrcdir)/config/rules.mk + +DEFINES += -DEXPORT_XPTC_API + +INCLUDES += -I$(srcdir)/../.. diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcinvoke_emx.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcinvoke_emx.cpp new file mode 100644 index 00000000..17fcadfe --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcinvoke_emx.cpp @@ -0,0 +1,185 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * John Fairhurst <john_fairhurst@iname.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** + * + * This Original Code has been modified by IBM Corporation. + * Modifications made by IBM described herein are + * Copyright (c) International Business Machines + * Corporation, 2000 + * + * Modifications to Mozilla code or documentation + * identified per MPL Section 3.3 + * + * Date Modified by Description of modification + * 03/22/2000 IBM Corp. Fixed multiple inheritance bug in XPTC_InvokeByIndex to adjust the + * "that" (this) pointer appropriately. + */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +// This is 80% copied directly from other platforms; the assembler +// stuff is all my fault, though. (jmf) + +#if !defined(__EMX__) +#error "This code is for OS/2 EMX only" +#endif + +#include "xptcprivate.h" + +// Remember that these 'words' are 32-bit DWORDs +static PRUint32 +invoke_count_words( PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 result = 0; + + for(PRUint32 i = 0; i < paramCount; i++, s++) + { + if(s->IsPtrData()) + result++; + + else { + + switch(s->type) + { + // 64-bit types + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + case nsXPTType::T_DOUBLE : + result+=2; + break; + + // all others are dwords + default: + result++; + break; + } + } + } + return result; +} + + +static void +invoke_copy_to_stack( PRUint32* d, uint32 paramCount, nsXPTCVariant* s) +{ + for( PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + *((void**)d) = s->ptr; + + else { + + switch(s->type) + { + case nsXPTType::T_I8 : *((int8*) d) = s->val.i8; break; + case nsXPTType::T_I16 : *((int16*) d) = s->val.i16; break; + case nsXPTType::T_I32 : *((int32*) d) = s->val.i32; break; + case nsXPTType::T_I64 : *((int64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U8 : *((uint8*) d) = s->val.u8; break; + case nsXPTType::T_U16 : *((uint16*) d) = s->val.u16; break; + case nsXPTType::T_U32 : *((uint32*) d) = s->val.u32; break; + case nsXPTType::T_U64 : *((uint64*) 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 : *((PRBool*) 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; + } + } + } +} + + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex( nsISupports *that, PRUint32 index, + PRUint32 paramcount, nsXPTCVariant* params) +{ + int ibytes; + void *pStack; + int result = NS_OK; + + // Find size in bytes necessary for call + ibytes = 4 * invoke_count_words( paramcount, params); + + __asm__ __volatile__( + "movl %1, %%eax\n" /* load |ibytes| into eax */ + "subl %%eax, %%esp\n" /* make room on stack */ + "movl %%esp, %0" /* store base in |pStack| */ + : "=g" (pStack) /* %0 */ + : "g" (ibytes) /* %1 */ + : "ax", "memory", "sp" + ); + + // Fill in that gap in the stack with the params to the method + invoke_copy_to_stack( (PRUint32*) pStack, paramcount, params); + + // push the hidden 'this' parameter, traverse the vtable, + // and then call the method. + + __asm__ __volatile__( + "movl %2, %%eax\n" /* |that| ptr -> eax */ + "movl (%%eax), %%edx\n" /* vptr -> edx */ + "movl %3, %%ebx\n" + "shl $3, %%ebx\n" /* 8 bytes per method.. */ + "addl $8, %%ebx\n" /* ..plus 8 to skip over 1st 8 bytes of vtbl */ + + "addl %%ebx, %%edx\n" /* find appropriate vtbl entry */ + "movswl (%%edx),%%ecx\n" /* get possible |that| ptr adjustment value */ + "addl %%ecx, %%eax\n" /* adjust the |that| ptr (needed for multiple inheritance) */ + "pushl %%eax\n" /* enstack the possibly-adjusted |that| */ + + "addl $4, %%edx\n" /* ..add 4 more to get to the method's entry point */ + + "call (%%edx)\n" /* call method */ + "movl %%eax, %0\n" /* save rc in |result| */ + "movl %1, %%ebx\n" /* clear up stack */ + "addl $4, %%ebx\n" + "addl %%ebx, %%esp" + : "=g" (result) /* %0 */ + : "g" (ibytes), /* %1 */ + "g" (that), /* %2 */ + "g" (index) /* %3 */ + : "ax", "bx", "dx", "memory", "sp" + ); + + return result; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcinvoke_gcc_x86_os2.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcinvoke_gcc_x86_os2.cpp new file mode 100644 index 00000000..6bbb93b0 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcinvoke_gcc_x86_os2.cpp @@ -0,0 +1,159 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Platform specific code to invoke XPCOM methods on native objects */
+
+/* This file is basically a copy of xptcinvoke_gcc_x86_unix.cpp with some
+ * irrelevant parts stipped off and some OS/2 specific modifications added,
+ * so it needs to be kept in sync with the original. */
+
+#include "xptcprivate.h"
+#include "xptc_platforms_unixish_x86.h"
+#include "xptc_gcc_x86_unix.h"
+
+extern "C" {
+static
+void ATTRIBUTE_USED __attribute__ ((regparm(3)))
+invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d)
+{
+ for(PRUint32 i = paramCount; i >0; i--, d++, s++)
+ {
+ if(s->IsPtrData())
+ {
+ *((void**)d) = s->ptr;
+ continue;
+ }
+
+ switch(s->type)
+ {
+ case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break;
+ case nsXPTType::T_U64 : *((PRUint64*)d) = s->val.u64; d++; break;
+ case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; break;
+ default : *((void**)d) = s->val.p; break;
+ }
+ }
+}
+} // extern "C"
+
+/*
+ XPTC_PUBLIC_API(nsresult)
+ XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
+ PRUint32 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
+
+ NOTE NOTE NOTE:
+ As of 2002-04-29 this function references no global variables nor does
+ it call non-static functions so preserving and loading the PIC register
+ is unnecessary. Define MOZ_PRESERVE_PIC if this changes. See mozilla
+ bug 140412 for details. However, avoid this if you can. It's slower.
+*/
+
+#if defined(__declspec)
+#define SYMBOL_EXPORT(sym) \
+ ".stabs \"" sym ",0=" sym ",code\", 0x6c,0,0,-42\n\t"
+#else
+#define SYMBOL_EXPORT(sym)
+#endif
+
+__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 " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex\n\t"
+ ".type " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex,@function\n"
+ SYMBOL_EXPORT(SYMBOL_UNDERSCORE "XPTC_InvokeByIndex")
+ SYMBOL_UNDERSCORE "XPTC_InvokeByIndex:\n\t"
+ "pushl %ebp\n\t"
+ "movl %esp, %ebp\n\t"
+#ifdef MOZ_PRESERVE_PIC
+ "pushl %ebx\n\t"
+ "call 0f\n\t"
+ ".subsection 1\n"
+ "0:\n\t"
+ "movl (%esp), %ebx\n\t"
+ "ret\n\t"
+ ".previous\n\t"
+ "addl $_GLOBAL_OFFSET_TABLE_, %ebx\n\t"
+#endif
+ "movl 0x10(%ebp), %eax\n\t"
+ "leal 0(,%eax,8),%edx\n\t"
+ "movl %esp, %ecx\n\t"
+ "subl %edx, %ecx\n\t"
+/* Since there may be 64-bit data, it occurs to me that aligning this
+ space might be a performance gain. However, I don't think the rest
+ of mozilla worries about such things. In any event, do it here.
+ "andl $0xfffffff8, %ecx\n\t"
+ */
+ "movl %ecx, %esp\n\t" /* make stack space */
+ "movl 0x14(%ebp), %edx\n\t"
+ "call " SYMBOL_UNDERSCORE "invoke_copy_to_stack\n\t"
+ "movl 0x08(%ebp), %ecx\n\t" /* 'that' */
+#ifdef CFRONT_STYLE_THIS_ADJUST
+ "movl (%ecx), %edx\n\t"
+ "movl 0x0c(%ebp), %eax\n\t" /* function index */
+ "shll $3, %eax\n\t" /* *= 8 */
+ "addl $8, %eax\n\t" /* += 8 skip first entry */
+ "addl %eax, %edx\n\t"
+ "movswl (%edx), %eax\n\t" /* 'this' offset */
+ "addl %eax, %ecx\n\t"
+ "pushl %ecx\n\t"
+ "addl $4, %edx\n\t" /* += 4, method pointer */
+#else /* THUNK_BASED_THIS_ADJUST */
+ "pushl %ecx\n\t"
+ "movl (%ecx), %edx\n\t"
+ "movl 0x0c(%ebp), %eax\n\t" /* function index */
+ "leal (%edx,%eax,4), %edx\n\t"
+#endif
+ "call *(%edx)\n\t"
+#ifdef MOZ_PRESERVE_PIC
+ "movl -4(%ebp), %ebx\n\t"
+#endif
+ "movl %ebp, %esp\n\t"
+ "popl %ebp\n\t"
+ "ret\n"
+ ".size " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex, . -" SYMBOL_UNDERSCORE "XPTC_InvokeByIndex\n\t"
+);
+
diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcinvoke_vacpp.asm b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcinvoke_vacpp.asm new file mode 100644 index 00000000..4d013fdb --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcinvoke_vacpp.asm @@ -0,0 +1,268 @@ +COMMENT | -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*- + + ***** BEGIN LICENSE BLOCK ***** + Version: MPL 1.1/GPL 2.0/LGPL 2.1 + + The contents of this file are subject to the Mozilla Public License Version + 1.1 (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + for the specific language governing rights and limitations under the + License. + + The Original Code is mozilla.org Code. + + The Initial Developer of the Original Code is + Netscape Communications Corporation. + Portions created by the Initial Developer are Copyright (C) 2001 + the Initial Developer. All Rights Reserved. + + Contributor(s): + Henry Sobotka <sobotka@axess.com> + + Alternatively, the contents of this file may be used under the terms of + either of the GNU General Public License Version 2 or later (the "GPL"), + or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + in which case the provisions of the GPL or the LGPL are applicable instead + of those above. If you wish to allow use of your version of this file only + under the terms of either the GPL or the LGPL, and not to allow others to + use your version of this file under the terms of the MPL, indicate your + decision by deleting the provisions above and replace them with the notice + and other provisions required by the GPL or the LGPL. If you do not delete + the provisions above, a recipient may use your version of this file under + the terms of any one of the MPL, the GPL or the LGPL. + + ***** END LICENSE BLOCK ***** + Version 1.0 (the "NPL"); you may not use this file except in + compliance with the NPL. You may obtain a copy of the NPL at + http://www.mozilla.org/NPL/ + + Software distributed under the NPL is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + for the specific language governing rights and limitations under the + NPL. + + The Initial Developer of this code under the NPL is Netscape + Communications Corporation. Portions created by Netscape are + Copyright (C) 1999 Netscape Communications Corporation. All Rights + Reserved. + + Contributor: Henry Sobotka <sobotka@axess.com> + + This Original Code has been modified by IBM Corporation. + Modifications made by IBM described herein are + Copyright (c) International Business Machines + Corporation, 2000 + + Modifications to Mozilla code or documentation + identified per MPL Section 3.3 + + Date Modified by Description of modification + 03/23/2000 IBM Corp. Various fixes for parameter passing and adjusting the 'this' + pointer for multiply inherited objects. + + xptcall_vacpp.asm: ALP assembler procedures for VAC++ build of xptcall + + We use essentially the same algorithm as the other platforms, except + Optlink as calling convention. This means loading the three leftmost + conforming (<= 4 bytes, enum or pointer) parameters into eax, edx and ecx, + and the four leftmost float types atop the FP stack. As "this" goes into + eax, we only have to load edx and ecx (if there are two parameters). + Nonconforming parameters go on the stack. As the right-size space has + to be allocated at the proper place (order of parameters) in the stack + for each conforming parameter, we simply copy them all. | + + + .486P + .MODEL FLAT, OPTLINK + .STACK + + .CODE + +t_Int4Bytes equ 001004h +t_Int8Bytes equ 001008h +t_Float4Bytes equ 000104h +t_Float8Bytes equ 000108h + +TypesArray dd t_Int4Bytes ; nsXPTType::T_I8 + dd t_Int4Bytes ; nsXPTType::T_I16 + dd t_Int4Bytes ; nsXPTType::T_I32 + dd t_Int8Bytes ; nsXPTType::T_I64 (***) + dd t_Int4Bytes ; nsXPTType::T_U8 + dd t_Int4Bytes ; nsXPTType::T_U16 + dd t_Int4Bytes ; nsXPTType::T_U32 + dd t_Int8Bytes ; nsXPTType::T_U64 (***) + dd t_Float4Bytes ; nsXPTType::T_FLOAT (***) + dd t_Float8Bytes ; nsXPTType::T_DOUBLE (***) + dd t_Int4Bytes ; nsXPTType::T_BOOL + dd t_Int4Bytes ; nsXPTType::T_CHAR + dd t_Int4Bytes ; nsXPTType::T_WCHAR + dd t_Int4Bytes ; TD_VOID + dd t_Int4Bytes ; TD_PNSIID + dd t_Int4Bytes ; TD_DOMSTRING + dd t_Int4Bytes ; TD_PSTRING + dd t_Int4Bytes ; TD_PWSTRING + dd t_Int4Bytes ; TD_INTERFACE_TYPE + dd t_Int4Bytes ; TD_INTERFACE_IS_TYPE + dd t_Int4Bytes ; TD_ARRAY + dd t_Int4Bytes ; TD_PSTRING_SIZE_IS + dd t_Int4Bytes ; TD_PWSTRING_SIZE_IS + dd t_Int4Bytes ; TD_UTF8STRING + dd t_Int4Bytes ; TD_CSTRING + dd t_Int4Bytes ; TD_ASTRING + ; All other values default to 4 byte int/ptr + + + + ; Optlink puts 'that' in eax, 'index' in edx, 'paramcount' in ecx + ; 'params' is on the stack... +XPTC_InvokeByIndex PROC OPTLINK EXPORT USES ebx edi esi, that, index, paramcount, params + + LOCAL cparams:dword, fparams:dword, reg_edx:dword, reg_ecx:dword, count:dword + + mov dword ptr [that], eax ; that + mov dword ptr [index], edx ; index + mov dword ptr [paramcount], ecx ; paramcount + mov dword ptr [count], ecx ; save a copy of count + +; #define FOURBYTES 4 +; #define EIGHTBYTES 8 +; #define FLOAT 0x00000100 +; #define INT 0x00001000 +; #define LENGTH 0x000000ff +; +;types[ ] = { +; FOURBYES | INT, // int/uint/ptr/etc +; EIGHTBYTES | INT, // long long +; FOURBYES | FLOAT, // float +; EIGHTBYTES | FLOAT // double +;}; +; params+00h = val // double +; params+08h = ptr +; params+0ch = type +; params+0dh = flags +; PTR_IS_DATA = 0x01 +; ecx = params +; edx = src +; edi = dst +; ebx = type (bh = int/float, bl = byte count) + + xor eax, eax + mov dword ptr [cparams],eax ; cparams = 0; + mov dword ptr [fparams],eax ; fparams = 0; + + shl ecx, 03h + sub esp, ecx ; dst/esp = add esp, paramCount * 8 + mov edi, esp + + push eax ; push 0 // "end" of floating point register stack... + + mov ecx, dword ptr [params] ; // params is a "register" variable +@While1: + mov eax, dword ptr [count] ; while( count-- ) + or eax, eax ; // (test for zero) + je @EndWhile1 + dec eax + mov dword ptr [count], eax + ; { + + test byte ptr [ecx+0dh],01h ; if ( params->flags & PTR_IS_DATA ) { + je @IfElse1 + lea edx, dword ptr [ecx+08h] ; src = ¶ms->ptr; + mov ebx, 01004h ; type = INT | FOURBYTES; + jmp @EndIf1 +@IfElse1: ; } else { + mov edx, ecx ; src = ¶ms->val + movzx eax, byte ptr [ecx+0ch] ; type = types[params->type]; + cmp eax, 22 ; // range check params->type... (0 to 22) + jle @TypeOK + mov eax,2 ; // all others default to 4 byte int +@TypeOK: + mov ebx, dword ptr [TypesArray+eax*4] +@EndIf1: ; } + + test bh, 001h ; if ( type & FLOAT ) { + je @EndIf2 + cmp dword ptr [fparams], 4 ; if ( fparams < 4 ) { + jge @EndIf3 + push edx ; push src; + push ebx ; push type + inc dword ptr [fparams] ; fparams++; +;;; movzx eax, bl ; // dst += (type & LENGTH); +;;; add edi, eax ; +;;; xor ebx, ebx ; // type = 0; // "handled" +@EndIf3: ; } +@EndIf2: ; } + + ; // copy bytes... +@While2: or bl, bl ; while( type & LENGTH ) { + je @EndWhile2 + test bh, 010h ; if( type & INT ) { + je @EndIf4 + cmp dword ptr [cparams], 8 ; if( cparams < 8 ) { + jge @EndIf5 + lea eax, dword ptr [reg_edx] ; (®_edx)[cparams] = *src; + sub eax, dword ptr [cparams] + mov esi, dword ptr [edx] + mov dword ptr [eax], esi + add dword ptr [cparams], 4 ; cparams += 4; +;;; jmp @NoCopy ; // goto nocopy; +@EndIf5: ; } +@EndIf4: ; } + mov eax, dword ptr [edx] ; *dst = *src; + mov dword ptr [edi], eax +@NoCopy: ;nocopy: + add edi, 4 ; dst++; + add edx, 4 ; src++; + sub bl, 4 ; type -= 4; + jmp @While2 +@EndWhile2: ; } + add ecx, 010h ; params++; + jmp @While1 +@EndWhile1: ; } + + ; // Set up fpu and regs can make the call... +@While3: pop ebx ; while ( pop type ) { + or ebx, ebx + je @EndWhile3 + pop edx ; pop src + cmp bl, 08h ; if( type & EIGHTBYTES ) { + jne @IfElse6 + fld qword ptr [edx] ; fld qword ptr [src] + jmp @EndIf6 +@IfElse6: ; } else { + fld dword ptr [edx] ; fld dword ptr [src] +@EndIf6: ; } + jmp @While3 +@EndWhile3: ; } + + ; make the call + mov eax, dword ptr [that] ; get 'that' ("this" ptr) + mov ebx, dword ptr [index] ; get index + shl ebx, 03h ; index *= 8 bytes per method + add ebx, 08h ; += 8 at head of vtable + add ebx, [eax] ; calculate address + + mov ecx, dword ptr [ebx+04h] + add eax, ecx + sub esp, 04h ; make room for 'this' ptr on stack + + mov edx, dword ptr [reg_edx] + mov ecx, dword ptr [reg_ecx] + + call dword ptr [ebx] ; call method + + mov ecx, dword ptr [paramcount] + shl ecx, 03h + add esp, ecx ; remove space on stack for params + add esp, 04h ; remove space on stack for 'this' ptr + ret + + ENDP + + END + + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_emx.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_emx.cpp new file mode 100644 index 00000000..6cde9231 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_emx.cpp @@ -0,0 +1,153 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods */ + +// This is a 98% copy of other implementations; see comment at top of +// xptcinvoke_emx.cpp for why this file exists. +// + +#include "xptcprivate.h" + +#if !defined(__EMX__) +#error "This code is for OS/2 EMX only" +#endif + +static nsresult +PrepareAndDispatch( nsXPTCStubBase *self, PRUint32 methodIndex, + PRUint32 *args) +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 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->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* 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 = *((PRInt8*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt16*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) ap); break; + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U8 : dp->val.u8 = *((PRUint8*) ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint16*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)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 = *((PRBool*) 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_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + register void* method = PrepareAndDispatch; \ + register nsresult result; \ + __asm__ __volatile__( \ + "leal 0x0c(%%ebp), %%ecx\n\t" /* args */ \ + "pushl %%ecx\n\t" \ + "pushl $"#n"\n\t" /* method index */ \ + "movl 0x08(%%ebp), %%ecx\n\t" /* this */ \ + "pushl %%ecx\n\t" \ + "call *%%edx" /* PrepareAndDispatch */ \ + : "=a" (result) /* %0 */ \ + : "d" (method) /* %1 */ \ + : "ax", "dx", "cx", "memory" ); \ + return result; \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPCWrappedJS::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_gcc_x86_os2.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_gcc_x86_os2.cpp new file mode 100644 index 00000000..6304b67a --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_gcc_x86_os2.cpp @@ -0,0 +1,180 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Implement shared vtbl methods. */
+
+/* This file is basically a copy of xptcinvoke_gcc_x86_unix.cpp with some
+ * irrelevant parts stipped off and some OS/2 specific modifications added,
+ * so it needs to be kept in sync with the original. */
+
+#include "xptcprivate.h"
+#include "xptc_platforms_unixish_x86.h"
+#include "xptc_gcc_x86_unix.h"
+
+extern "C" {
+static nsresult ATTRIBUTE_USED
+__attribute__ ((regparm (3)))
+PrepareAndDispatch(uint32 methodIndex, nsXPTCStubBase* self, PRUint32* args)
+{
+#define PARAM_BUFFER_COUNT 16
+
+ nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
+ nsXPTCMiniVariant* dispatchParams = NULL;
+ nsIInterfaceInfo* iface_info = NULL;
+ const nsXPTMethodInfo* info = NULL;
+ PRUint8 paramCount;
+ PRUint8 i;
+ nsresult result = NS_ERROR_FAILURE;
+
+ NS_ASSERTION(self,"no self");
+
+ self->GetInterfaceInfo(&iface_info);
+ NS_ASSERTION(iface_info,"no interface info");
+ if (!iface_info)
+ return NS_ERROR_UNEXPECTED;
+
+ iface_info->GetMethodInfo(PRUint16(methodIndex), &info);
+ NS_ASSERTION(info,"no method info");
+ if (!info)
+ return NS_ERROR_UNEXPECTED;
+
+ 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");
+ if (!dispatchParams)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ PRUint32* 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
+ dp->val.p = (void*) *ap;
+ switch(type)
+ {
+ case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break;
+ case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)ap); ap++; break;
+ case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); ap++; break;
+ }
+ }
+
+ result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);
+
+ NS_RELEASE(iface_info);
+
+ if(dispatchParams != paramBuffer)
+ delete [] dispatchParams;
+
+ return result;
+}
+} // extern "C"
+
+#if defined(__declspec)
+#define SYMBOL_EXPORT(sym) \
+ ".stabs \"" sym ",0=" sym ",code\", 0x6c,0,0,-42\n\t"
+#else
+#define SYMBOL_EXPORT(sym)
+#endif
+
+#define STUB_ENTRY(n) \
+asm(".text\n\t" \
+ ".align 2\n\t" \
+ ".if " #n " < 10\n\t" \
+ ".globl " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev\n\t" \
+ ".type " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev,@function\n" \
+ SYMBOL_EXPORT(SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev") \
+ SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev:\n\t" \
+ ".elseif " #n " < 100\n\t" \
+ ".globl " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev\n\t" \
+ ".type " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev,@function\n" \
+ SYMBOL_EXPORT(SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev") \
+ SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev:\n\t" \
+ ".elseif " #n " < 1000\n\t" \
+ ".globl " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev\n\t" \
+ ".type " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev,@function\n" \
+ SYMBOL_EXPORT(SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev") \
+ SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev:\n\t" \
+ ".else\n\t" \
+ ".err \"stub number " #n " >= 1000 not yet supported\"\n\t" \
+ ".endif\n\t" \
+ "movl $" #n ", %eax\n\t" \
+ "jmp " SYMBOL_UNDERSCORE "SharedStub\n\t" \
+ ".if " #n " < 10\n\t" \
+ ".size " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev,.-" SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev\n\t" \
+ ".elseif " #n " < 100\n\t" \
+ ".size " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev,.-" SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev\n\t" \
+ ".else\n\t" \
+ ".size " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev,.-" SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev\n\t" \
+ ".endif");
+
+// static nsresult SharedStub(PRUint32 methodIndex) __attribute__((regparm(1)))
+asm(".text\n\t"
+ ".align 2\n\t"
+ ".type " SYMBOL_UNDERSCORE "SharedStub,@function\n\t"
+ SYMBOL_UNDERSCORE "SharedStub:\n\t"
+ "leal 0x08(%esp), %ecx\n\t"
+ "movl 0x04(%esp), %edx\n\t"
+ "jmp " SYMBOL_UNDERSCORE "PrepareAndDispatch\n\t"
+ ".size " SYMBOL_UNDERSCORE "SharedStub,.-" SYMBOL_UNDERSCORE "SharedStub");
+
+#define SENTINEL_ENTRY(n) \
+nsresult nsXPTCStubBase::Sentinel##n() \
+{ \
+ NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
+ return NS_ERROR_NOT_IMPLEMENTED; \
+}
+
+#include "xptcstubsdef.inc"
+
+void
+xptc_dummy()
+{
+}
+
diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_os2.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_os2.cpp new file mode 100644 index 00000000..33e8574a --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_os2.cpp @@ -0,0 +1,195 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org Code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * John Fairhurst <john_fairhurst@iname.com> + * Henry Sobotka <sobotka@axess.com> added VAC++ support + * and fixed emx asm to work with gcc 2.95.2 (Jan. 2000) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods */ + +#include "xptcprivate.h" + +#if !defined (__EMX__) && !defined(__IBMCPP__) +#error "This code is only for OS/2" +#endif + +// Procedure in xptcall_vacpp.asm +#ifdef XP_OS2_VACPP +extern nsresult SetEntryFromIndex(int stubidx); +#endif + +#ifdef XP_OS2_VACPP +nsresult +PrepareAndDispatch( nsXPTCStubBase *self, PRUint32 methodIndex, + PRUint32 *args) +#else +static nsresult +PrepareAndDispatch( nsXPTCStubBase *self, PRUint32 methodIndex, + PRUint32 *args) +#endif +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 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->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no interface info"); + + paramCount = info->GetParamCount(); + +#ifdef XP_OS2_VACPP + /* If paramCount is > 0, write out the EDX pointer to the + space on the stack args[0]. args[-4] is the space on + the stack where it was pushed */ + if (paramCount) { + args[0] = args[-4]; + + /* If this is the second parameter, or if the first parameter is an + 8 byte long long, write out the ECX pointer to the space on the + stack args[1]. args[-3] is the space on the stack where it was + pushed */ + nsXPTType type = info->GetParam(0).GetType(); + if( paramCount > 1 || + type == nsXPTType::T_I64 || type == nsXPTType::T_U64 ) + { + args[1] = args[-3]; + } + } +#endif + + // setup variant array pointer + if(paramCount > PARAM_BUFFER_COUNT) + dispatchParams = new nsXPTCMiniVariant[paramCount]; + else + dispatchParams = paramBuffer; + NS_ASSERTION(dispatchParams,"no place for params"); + + PRUint32* 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 = *((PRInt8*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt16*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) ap); break; + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U8 : dp->val.u8 = *((PRUint8*) ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint16*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)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 = *((PRBool*) 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_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#ifdef XP_OS2_VACPP + +#define STUB_ENTRY(n) + +#else + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + register nsresult (*method) (nsXPTCStubBase *, PRUint32, PRUint32 *) = PrepareAndDispatch; \ + int temp0, temp1; \ + register nsresult result; \ + __asm__ __volatile__( \ + "leal 0x0c(%%ebp), %%ecx\n\t" /* args */ \ + "pushl %%ecx\n\t" \ + "pushl $"#n"\n\t" /* method index */ \ + "movl 0x08(%%ebp), %%ecx\n\t" /* this */ \ + "pushl %%ecx\n\t" \ + "call *%%edx\n\t" /* PrepareAndDispatch */ \ + "addl $12, %%esp" \ + : "=a" (result), /* %0 */ \ + "=&c" (temp0), /* %1 */ \ + "=d" (temp1) /* %2 */ \ + : "2" (method) /* %2 */ \ + : "memory" ); \ + return result; \ +} +#endif + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPCWrappedJS::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_vacpp.asm b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_vacpp.asm new file mode 100644 index 00000000..3464a1f9 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/os2/xptcstubs_vacpp.asm @@ -0,0 +1,1563 @@ +COMMENT | -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*- + + ***** BEGIN LICENSE BLOCK ***** + Version: MPL 1.1/GPL 2.0/LGPL 2.1 + + The contents of this file are subject to the Mozilla Public License Version + 1.1 (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + for the specific language governing rights and limitations under the + License. + + The Original Code is mozilla.org Code. + + The Initial Developer of the Original Code is + Netscape Communications Corporation. + Portions created by the Initial Developer are Copyright (C) 2001 + the Initial Developer. All Rights Reserved. + + Contributor(s): + John Fairhurst <john_fairhurst@iname.com> + Henry Sobotka <sobotka@axess.com> + + Alternatively, the contents of this file may be used under the terms of + either of the GNU General Public License Version 2 or later (the "GPL"), + or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + in which case the provisions of the GPL or the LGPL are applicable instead + of those above. If you wish to allow use of your version of this file only + under the terms of either the GPL or the LGPL, and not to allow others to + use your version of this file under the terms of the MPL, indicate your + decision by deleting the provisions above and replace them with the notice + and other provisions required by the GPL or the LGPL. If you do not delete + the provisions above, a recipient may use your version of this file under + the terms of any one of the MPL, the GPL or the LGPL. + + ***** END LICENSE BLOCK ***** + Version 1.0 (the "NPL"); you may not use this file except in + compliance with the NPL. You may obtain a copy of the NPL at + http://www.mozilla.org/NPL/ + + Software distributed under the NPL is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + for the specific language governing rights and limitations under the + NPL. + + The Initial Developer of this code under the NPL is Netscape + Communications Corporation. Portions created by Netscape are + Copyright (C) 1999 Netscape Communications Corporation. All Rights + Reserved. + + Contributor: Henry Sobotka <sobotka@axess.com> + + xptcallstub_vacpp.asm: ALP assembler procedure for VAC++ build of xptcall + | + + .486P + .MODEL FLAT, OPTLINK + .STACK + + .CODE + + EXTERN OPTLINK PrepareAndDispatch__FP14nsXPTCStubBaseUiPUi:PROC + +setentidx MACRO index + + push ecx ; Save parameters + push edx ; Save parameters - don't need to save eax - it is the "this" ptr + lea ecx, dword ptr [esp+10h] ; Load pointer to "args" into ecx + mov edx, index ; Move vtable index into edx + sub esp, 0ch ; Make room for three parameters on the stack + call PrepareAndDispatch__FP14nsXPTCStubBaseUiPUi + add esp, 14h ; Reset stack pointer + ret + ENDM + +; 251 STUB_ENTRY(249) + +Stub249__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f9h +Stub249__14nsXPTCStubBaseFv endp + +; 250 STUB_ENTRY(248) + +Stub248__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f8h +Stub248__14nsXPTCStubBaseFv endp + +; 249 STUB_ENTRY(247) + +Stub247__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f7h +Stub247__14nsXPTCStubBaseFv endp + +; 248 STUB_ENTRY(246) + +Stub246__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f6h +Stub246__14nsXPTCStubBaseFv endp + +; 247 STUB_ENTRY(245) + +Stub245__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f5h +Stub245__14nsXPTCStubBaseFv endp + +; 246 STUB_ENTRY(244) + +Stub244__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f4h +Stub244__14nsXPTCStubBaseFv endp + +; 245 STUB_ENTRY(243) + +Stub243__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f3h +Stub243__14nsXPTCStubBaseFv endp + +; 244 STUB_ENTRY(242) + +Stub242__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f2h +Stub242__14nsXPTCStubBaseFv endp + +; 243 STUB_ENTRY(241) + +Stub241__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f1h +Stub241__14nsXPTCStubBaseFv endp + +; 242 STUB_ENTRY(240) + +Stub240__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0f0h +Stub240__14nsXPTCStubBaseFv endp + +; 241 STUB_ENTRY(239) + +Stub239__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0efh +Stub239__14nsXPTCStubBaseFv endp + +; 240 STUB_ENTRY(238) + +Stub238__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0eeh +Stub238__14nsXPTCStubBaseFv endp + +; 239 STUB_ENTRY(237) + +Stub237__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0edh +Stub237__14nsXPTCStubBaseFv endp + +; 238 STUB_ENTRY(236) + +Stub236__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0ech +Stub236__14nsXPTCStubBaseFv endp + +; 237 STUB_ENTRY(235) + +Stub235__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0ebh +Stub235__14nsXPTCStubBaseFv endp + +; 236 STUB_ENTRY(234) + +Stub234__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0eah +Stub234__14nsXPTCStubBaseFv endp + +; 235 STUB_ENTRY(233) + +Stub233__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e9h +Stub233__14nsXPTCStubBaseFv endp + +; 234 STUB_ENTRY(232) + +Stub232__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e8h +Stub232__14nsXPTCStubBaseFv endp + +; 233 STUB_ENTRY(231) + +Stub231__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e7h +Stub231__14nsXPTCStubBaseFv endp + +; 232 STUB_ENTRY(230) + +Stub230__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e6h +Stub230__14nsXPTCStubBaseFv endp + +; 231 STUB_ENTRY(229) + +Stub229__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e5h +Stub229__14nsXPTCStubBaseFv endp + +; 230 STUB_ENTRY(228) + +Stub228__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e4h +Stub228__14nsXPTCStubBaseFv endp + +; 229 STUB_ENTRY(227) + +Stub227__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e3h +Stub227__14nsXPTCStubBaseFv endp + +; 228 STUB_ENTRY(226) + +Stub226__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e2h +Stub226__14nsXPTCStubBaseFv endp + +; 227 STUB_ENTRY(225) + +Stub225__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e1h +Stub225__14nsXPTCStubBaseFv endp + +; 226 STUB_ENTRY(224) + +Stub224__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0e0h +Stub224__14nsXPTCStubBaseFv endp + +; 225 STUB_ENTRY(223) + +Stub223__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0dfh +Stub223__14nsXPTCStubBaseFv endp + +; 224 STUB_ENTRY(222) + +Stub222__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0deh +Stub222__14nsXPTCStubBaseFv endp + +; 223 STUB_ENTRY(221) + +Stub221__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0ddh +Stub221__14nsXPTCStubBaseFv endp + +; 222 STUB_ENTRY(220) + +Stub220__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0dch +Stub220__14nsXPTCStubBaseFv endp + +; 221 STUB_ENTRY(219) + +Stub219__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0dbh +Stub219__14nsXPTCStubBaseFv endp + +; 220 STUB_ENTRY(218) + +Stub218__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0dah +Stub218__14nsXPTCStubBaseFv endp + +; 219 STUB_ENTRY(217) + +Stub217__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d9h +Stub217__14nsXPTCStubBaseFv endp + +; 218 STUB_ENTRY(216) + +Stub216__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d8h +Stub216__14nsXPTCStubBaseFv endp + +; 217 STUB_ENTRY(215) + +Stub215__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d7h +Stub215__14nsXPTCStubBaseFv endp + +; 216 STUB_ENTRY(214) + +Stub214__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d6h +Stub214__14nsXPTCStubBaseFv endp + +; 215 STUB_ENTRY(213) + +Stub213__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d5h +Stub213__14nsXPTCStubBaseFv endp + +; 214 STUB_ENTRY(212) + +Stub212__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d4h +Stub212__14nsXPTCStubBaseFv endp + +; 213 STUB_ENTRY(211) + +Stub211__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d3h +Stub211__14nsXPTCStubBaseFv endp + +; 212 STUB_ENTRY(210) + +Stub210__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d2h +Stub210__14nsXPTCStubBaseFv endp + +; 211 STUB_ENTRY(209) + +Stub209__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d1h +Stub209__14nsXPTCStubBaseFv endp + +; 210 STUB_ENTRY(208) + +Stub208__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0d0h +Stub208__14nsXPTCStubBaseFv endp + +; 209 STUB_ENTRY(207) + +Stub207__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0cfh +Stub207__14nsXPTCStubBaseFv endp + +; 208 STUB_ENTRY(206) + +Stub206__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0ceh +Stub206__14nsXPTCStubBaseFv endp + +; 207 STUB_ENTRY(205) + +Stub205__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0cdh +Stub205__14nsXPTCStubBaseFv endp + +; 206 STUB_ENTRY(204) + +Stub204__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0cch +Stub204__14nsXPTCStubBaseFv endp + +; 205 STUB_ENTRY(203) + +Stub203__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0cbh +Stub203__14nsXPTCStubBaseFv endp + +; 204 STUB_ENTRY(202) + +Stub202__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0cah +Stub202__14nsXPTCStubBaseFv endp + +; 203 STUB_ENTRY(201) + +Stub201__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c9h +Stub201__14nsXPTCStubBaseFv endp + +; 202 STUB_ENTRY(200) + +Stub200__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c8h +Stub200__14nsXPTCStubBaseFv endp + +; 201 STUB_ENTRY(199) + +Stub199__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c7h +Stub199__14nsXPTCStubBaseFv endp + +; 200 STUB_ENTRY(198) + +Stub198__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c6h +Stub198__14nsXPTCStubBaseFv endp + +; 199 STUB_ENTRY(197) + +Stub197__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c5h +Stub197__14nsXPTCStubBaseFv endp + +; 198 STUB_ENTRY(196) + +Stub196__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c4h +Stub196__14nsXPTCStubBaseFv endp + +; 197 STUB_ENTRY(195) + +Stub195__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c3h +Stub195__14nsXPTCStubBaseFv endp + +; 196 STUB_ENTRY(194) + +Stub194__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c2h +Stub194__14nsXPTCStubBaseFv endp + +; 195 STUB_ENTRY(193) + +Stub193__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c1h +Stub193__14nsXPTCStubBaseFv endp + +; 194 STUB_ENTRY(192) + +Stub192__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0c0h +Stub192__14nsXPTCStubBaseFv endp + +; 193 STUB_ENTRY(191) + +Stub191__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0bfh +Stub191__14nsXPTCStubBaseFv endp + +; 192 STUB_ENTRY(190) + +Stub190__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0beh +Stub190__14nsXPTCStubBaseFv endp + +; 191 STUB_ENTRY(189) + +Stub189__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0bdh +Stub189__14nsXPTCStubBaseFv endp + +; 190 STUB_ENTRY(188) + +Stub188__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0bch +Stub188__14nsXPTCStubBaseFv endp + +; 189 STUB_ENTRY(187) + +Stub187__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0bbh +Stub187__14nsXPTCStubBaseFv endp + +; 188 STUB_ENTRY(186) + +Stub186__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0bah +Stub186__14nsXPTCStubBaseFv endp + +; 187 STUB_ENTRY(185) + +Stub185__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b9h +Stub185__14nsXPTCStubBaseFv endp + +; 186 STUB_ENTRY(184) + +Stub184__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b8h +Stub184__14nsXPTCStubBaseFv endp + +; 185 STUB_ENTRY(183) + +Stub183__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b7h +Stub183__14nsXPTCStubBaseFv endp + +; 184 STUB_ENTRY(182) + +Stub182__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b6h +Stub182__14nsXPTCStubBaseFv endp + +; 183 STUB_ENTRY(181) + +Stub181__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b5h +Stub181__14nsXPTCStubBaseFv endp + +; 182 STUB_ENTRY(180) + +Stub180__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b4h +Stub180__14nsXPTCStubBaseFv endp + +; 181 STUB_ENTRY(179) + +Stub179__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b3h +Stub179__14nsXPTCStubBaseFv endp + +; 180 STUB_ENTRY(178) + +Stub178__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b2h +Stub178__14nsXPTCStubBaseFv endp + +; 179 STUB_ENTRY(177) + +Stub177__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b1h +Stub177__14nsXPTCStubBaseFv endp + +; 178 STUB_ENTRY(176) + +Stub176__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0b0h +Stub176__14nsXPTCStubBaseFv endp + +; 177 STUB_ENTRY(175) + +Stub175__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0afh +Stub175__14nsXPTCStubBaseFv endp + +; 176 STUB_ENTRY(174) + +Stub174__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0aeh +Stub174__14nsXPTCStubBaseFv endp + +; 175 STUB_ENTRY(173) + +Stub173__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0adh +Stub173__14nsXPTCStubBaseFv endp + +; 174 STUB_ENTRY(172) + +Stub172__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0ach +Stub172__14nsXPTCStubBaseFv endp + +; 173 STUB_ENTRY(171) + +Stub171__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0abh +Stub171__14nsXPTCStubBaseFv endp + +; 172 STUB_ENTRY(170) + +Stub170__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0aah +Stub170__14nsXPTCStubBaseFv endp + +; 171 STUB_ENTRY(169) + +Stub169__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a9h +Stub169__14nsXPTCStubBaseFv endp + +; 170 STUB_ENTRY(168) + +Stub168__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a8h +Stub168__14nsXPTCStubBaseFv endp + +; 169 STUB_ENTRY(167) + +Stub167__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a7h +Stub167__14nsXPTCStubBaseFv endp + +; 168 STUB_ENTRY(166) + +Stub166__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a6h +Stub166__14nsXPTCStubBaseFv endp + +; 167 STUB_ENTRY(165) + +Stub165__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a5h +Stub165__14nsXPTCStubBaseFv endp + +; 166 STUB_ENTRY(164) + +Stub164__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a4h +Stub164__14nsXPTCStubBaseFv endp + +; 165 STUB_ENTRY(163) + +Stub163__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a3h +Stub163__14nsXPTCStubBaseFv endp + +; 164 STUB_ENTRY(162) + +Stub162__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a2h +Stub162__14nsXPTCStubBaseFv endp + +; 163 STUB_ENTRY(161) + +Stub161__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a1h +Stub161__14nsXPTCStubBaseFv endp + +; 162 STUB_ENTRY(160) + +Stub160__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0a0h +Stub160__14nsXPTCStubBaseFv endp + +; 161 STUB_ENTRY(159) + +Stub159__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 09fh +Stub159__14nsXPTCStubBaseFv endp + +; 160 STUB_ENTRY(158) + +Stub158__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 09eh +Stub158__14nsXPTCStubBaseFv endp + +; 159 STUB_ENTRY(157) + +Stub157__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 09dh +Stub157__14nsXPTCStubBaseFv endp + +; 158 STUB_ENTRY(156) + +Stub156__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 09ch +Stub156__14nsXPTCStubBaseFv endp + +; 157 STUB_ENTRY(155) + +Stub155__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 09bh +Stub155__14nsXPTCStubBaseFv endp + +; 156 STUB_ENTRY(154) + +Stub154__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 09ah +Stub154__14nsXPTCStubBaseFv endp + +; 155 STUB_ENTRY(153) + +Stub153__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 099h +Stub153__14nsXPTCStubBaseFv endp + +; 154 STUB_ENTRY(152) + +Stub152__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 098h +Stub152__14nsXPTCStubBaseFv endp + +; 153 STUB_ENTRY(151) + +Stub151__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 097h +Stub151__14nsXPTCStubBaseFv endp + +; 152 STUB_ENTRY(150) + +Stub150__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 096h +Stub150__14nsXPTCStubBaseFv endp + +; 151 STUB_ENTRY(149) + +Stub149__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 095h +Stub149__14nsXPTCStubBaseFv endp + +; 150 STUB_ENTRY(148) + +Stub148__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 094h +Stub148__14nsXPTCStubBaseFv endp + +; 149 STUB_ENTRY(147) + +Stub147__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 093h +Stub147__14nsXPTCStubBaseFv endp + +; 148 STUB_ENTRY(146) + +Stub146__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 092h +Stub146__14nsXPTCStubBaseFv endp + +; 147 STUB_ENTRY(145) + +Stub145__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 091h +Stub145__14nsXPTCStubBaseFv endp + +; 146 STUB_ENTRY(144) + +Stub144__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 090h +Stub144__14nsXPTCStubBaseFv endp + +; 145 STUB_ENTRY(143) + +Stub143__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 08fh +Stub143__14nsXPTCStubBaseFv endp + +; 144 STUB_ENTRY(142) + +Stub142__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 08eh +Stub142__14nsXPTCStubBaseFv endp + +; 143 STUB_ENTRY(141) + +Stub141__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 08dh +Stub141__14nsXPTCStubBaseFv endp + +; 142 STUB_ENTRY(140) + +Stub140__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 08ch +Stub140__14nsXPTCStubBaseFv endp + +; 141 STUB_ENTRY(139) + +Stub139__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 08bh +Stub139__14nsXPTCStubBaseFv endp + +; 140 STUB_ENTRY(138) + +Stub138__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 08ah +Stub138__14nsXPTCStubBaseFv endp + +; 139 STUB_ENTRY(137) + +Stub137__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 089h +Stub137__14nsXPTCStubBaseFv endp + +; 138 STUB_ENTRY(136) + +Stub136__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 088h +Stub136__14nsXPTCStubBaseFv endp + +; 137 STUB_ENTRY(135) + +Stub135__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 087h +Stub135__14nsXPTCStubBaseFv endp + +; 136 STUB_ENTRY(134) + +Stub134__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 086h +Stub134__14nsXPTCStubBaseFv endp + +; 135 STUB_ENTRY(133) + +Stub133__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 085h +Stub133__14nsXPTCStubBaseFv endp + +; 134 STUB_ENTRY(132) + +Stub132__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 084h +Stub132__14nsXPTCStubBaseFv endp + +; 133 STUB_ENTRY(131) + +Stub131__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 083h +Stub131__14nsXPTCStubBaseFv endp + +; 132 STUB_ENTRY(130) + +Stub130__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 082h +Stub130__14nsXPTCStubBaseFv endp + +; 131 STUB_ENTRY(129) + +Stub129__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 081h +Stub129__14nsXPTCStubBaseFv endp + +; 130 STUB_ENTRY(128) + +Stub128__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 080h +Stub128__14nsXPTCStubBaseFv endp + +; 129 STUB_ENTRY(127) + +Stub127__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 07fh +Stub127__14nsXPTCStubBaseFv endp + +; 128 STUB_ENTRY(126) + +Stub126__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 07eh +Stub126__14nsXPTCStubBaseFv endp + +; 127 STUB_ENTRY(125) + +Stub125__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 07dh +Stub125__14nsXPTCStubBaseFv endp + +; 126 STUB_ENTRY(124) + +Stub124__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 07ch +Stub124__14nsXPTCStubBaseFv endp + +; 125 STUB_ENTRY(123) + +Stub123__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 07bh +Stub123__14nsXPTCStubBaseFv endp + +; 124 STUB_ENTRY(122) + +Stub122__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 07ah +Stub122__14nsXPTCStubBaseFv endp + +; 123 STUB_ENTRY(121) + +Stub121__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 079h +Stub121__14nsXPTCStubBaseFv endp + +; 122 STUB_ENTRY(120) + +Stub120__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 078h +Stub120__14nsXPTCStubBaseFv endp + +; 121 STUB_ENTRY(119) + +Stub119__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 077h +Stub119__14nsXPTCStubBaseFv endp + +; 120 STUB_ENTRY(118) + +Stub118__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 076h +Stub118__14nsXPTCStubBaseFv endp + +; 119 STUB_ENTRY(117) + +Stub117__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 075h +Stub117__14nsXPTCStubBaseFv endp + +; 118 STUB_ENTRY(116) + +Stub116__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 074h +Stub116__14nsXPTCStubBaseFv endp + +; 117 STUB_ENTRY(115) + +Stub115__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 073h +Stub115__14nsXPTCStubBaseFv endp + +; 116 STUB_ENTRY(114) + +Stub114__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 072h +Stub114__14nsXPTCStubBaseFv endp + +; 115 STUB_ENTRY(113) + +Stub113__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 071h +Stub113__14nsXPTCStubBaseFv endp + +; 114 STUB_ENTRY(112) + +Stub112__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 070h +Stub112__14nsXPTCStubBaseFv endp + +; 113 STUB_ENTRY(111) + +Stub111__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 06fh +Stub111__14nsXPTCStubBaseFv endp + +; 112 STUB_ENTRY(110) + +Stub110__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 06eh +Stub110__14nsXPTCStubBaseFv endp + +; 111 STUB_ENTRY(109) + +Stub109__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 06dh +Stub109__14nsXPTCStubBaseFv endp + +; 110 STUB_ENTRY(108) + +Stub108__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 06ch +Stub108__14nsXPTCStubBaseFv endp + +; 109 STUB_ENTRY(107) + +Stub107__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 06bh +Stub107__14nsXPTCStubBaseFv endp + +; 108 STUB_ENTRY(106) + +Stub106__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 06ah +Stub106__14nsXPTCStubBaseFv endp + +; 107 STUB_ENTRY(105) + +Stub105__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 069h +Stub105__14nsXPTCStubBaseFv endp + +; 106 STUB_ENTRY(104) + +Stub104__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 068h +Stub104__14nsXPTCStubBaseFv endp + +; 105 STUB_ENTRY(103) + +Stub103__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 067h +Stub103__14nsXPTCStubBaseFv endp + +; 104 STUB_ENTRY(102) + +Stub102__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 066h +Stub102__14nsXPTCStubBaseFv endp + +; 103 STUB_ENTRY(101) + +Stub101__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 065h +Stub101__14nsXPTCStubBaseFv endp + +; 102 STUB_ENTRY(100) + +Stub100__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 064h +Stub100__14nsXPTCStubBaseFv endp + +; 101 STUB_ENTRY(99) + +Stub99__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 063h +Stub99__14nsXPTCStubBaseFv endp + +; 100 STUB_ENTRY(98) + +Stub98__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 062h +Stub98__14nsXPTCStubBaseFv endp + +; 99 STUB_ENTRY(97) + +Stub97__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 061h +Stub97__14nsXPTCStubBaseFv endp + +; 98 STUB_ENTRY(96) + +Stub96__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 060h +Stub96__14nsXPTCStubBaseFv endp + +; 97 STUB_ENTRY(95) + +Stub95__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 05fh +Stub95__14nsXPTCStubBaseFv endp + +; 96 STUB_ENTRY(94) + +Stub94__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 05eh +Stub94__14nsXPTCStubBaseFv endp + +; 95 STUB_ENTRY(93) + +Stub93__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 05dh +Stub93__14nsXPTCStubBaseFv endp + +; 94 STUB_ENTRY(92) + +Stub92__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 05ch +Stub92__14nsXPTCStubBaseFv endp + +; 93 STUB_ENTRY(91) + +Stub91__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 05bh +Stub91__14nsXPTCStubBaseFv endp + +; 92 STUB_ENTRY(90) + +Stub90__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 05ah +Stub90__14nsXPTCStubBaseFv endp + +; 91 STUB_ENTRY(89) + +Stub89__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 059h +Stub89__14nsXPTCStubBaseFv endp + +; 90 STUB_ENTRY(88) + +Stub88__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 058h +Stub88__14nsXPTCStubBaseFv endp + +; 89 STUB_ENTRY(87) + +Stub87__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 057h +Stub87__14nsXPTCStubBaseFv endp + +; 88 STUB_ENTRY(86) + +Stub86__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 056h +Stub86__14nsXPTCStubBaseFv endp + +; 87 STUB_ENTRY(85) + +Stub85__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 055h +Stub85__14nsXPTCStubBaseFv endp + +; 86 STUB_ENTRY(84) + +Stub84__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 054h +Stub84__14nsXPTCStubBaseFv endp + +; 85 STUB_ENTRY(83) + +Stub83__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 053h +Stub83__14nsXPTCStubBaseFv endp + +; 84 STUB_ENTRY(82) + +Stub82__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 052h +Stub82__14nsXPTCStubBaseFv endp + +; 83 STUB_ENTRY(81) + +Stub81__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 051h +Stub81__14nsXPTCStubBaseFv endp + +; 82 STUB_ENTRY(80) + +Stub80__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 050h +Stub80__14nsXPTCStubBaseFv endp + +; 81 STUB_ENTRY(79) + +Stub79__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 04fh +Stub79__14nsXPTCStubBaseFv endp + +; 80 STUB_ENTRY(78) + +Stub78__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 04eh +Stub78__14nsXPTCStubBaseFv endp + +; 79 STUB_ENTRY(77) + +Stub77__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 04dh +Stub77__14nsXPTCStubBaseFv endp + +; 78 STUB_ENTRY(76) + +Stub76__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 04ch +Stub76__14nsXPTCStubBaseFv endp + +; 77 STUB_ENTRY(75) + +Stub75__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 04bh +Stub75__14nsXPTCStubBaseFv endp + +; 76 STUB_ENTRY(74) + +Stub74__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 04ah +Stub74__14nsXPTCStubBaseFv endp + +; 75 STUB_ENTRY(73) + +Stub73__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 049h +Stub73__14nsXPTCStubBaseFv endp + +; 74 STUB_ENTRY(72) + +Stub72__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 048h +Stub72__14nsXPTCStubBaseFv endp + +; 73 STUB_ENTRY(71) + +Stub71__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 047h +Stub71__14nsXPTCStubBaseFv endp + +; 72 STUB_ENTRY(70) + +Stub70__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 046h +Stub70__14nsXPTCStubBaseFv endp + +; 71 STUB_ENTRY(69) + +Stub69__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 045h +Stub69__14nsXPTCStubBaseFv endp + +; 70 STUB_ENTRY(68) + +Stub68__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 044h +Stub68__14nsXPTCStubBaseFv endp + +; 69 STUB_ENTRY(67) + +Stub67__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 043h +Stub67__14nsXPTCStubBaseFv endp + +; 68 STUB_ENTRY(66) + +Stub66__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 042h +Stub66__14nsXPTCStubBaseFv endp + +; 67 STUB_ENTRY(65) + +Stub65__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 041h +Stub65__14nsXPTCStubBaseFv endp + +; 66 STUB_ENTRY(64) + +Stub64__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 040h +Stub64__14nsXPTCStubBaseFv endp + +; 65 STUB_ENTRY(63) + +Stub63__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 03fh +Stub63__14nsXPTCStubBaseFv endp + +; 64 STUB_ENTRY(62) + +Stub62__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 03eh +Stub62__14nsXPTCStubBaseFv endp + +; 63 STUB_ENTRY(61) + +Stub61__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 03dh +Stub61__14nsXPTCStubBaseFv endp + +; 62 STUB_ENTRY(60) + +Stub60__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 03ch +Stub60__14nsXPTCStubBaseFv endp + +; 61 STUB_ENTRY(59) + +Stub59__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 03bh +Stub59__14nsXPTCStubBaseFv endp + +; 60 STUB_ENTRY(58) + +Stub58__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 03ah +Stub58__14nsXPTCStubBaseFv endp + +; 59 STUB_ENTRY(57) + +Stub57__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 039h +Stub57__14nsXPTCStubBaseFv endp + +; 58 STUB_ENTRY(56) + +Stub56__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 038h +Stub56__14nsXPTCStubBaseFv endp + +; 57 STUB_ENTRY(55) + +Stub55__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 037h +Stub55__14nsXPTCStubBaseFv endp + +; 56 STUB_ENTRY(54) + +Stub54__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 036h +Stub54__14nsXPTCStubBaseFv endp + +; 55 STUB_ENTRY(53) + +Stub53__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 035h +Stub53__14nsXPTCStubBaseFv endp + +; 54 STUB_ENTRY(52) + +Stub52__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 034h +Stub52__14nsXPTCStubBaseFv endp + +; 53 STUB_ENTRY(51) + +Stub51__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 033h +Stub51__14nsXPTCStubBaseFv endp + +; 52 STUB_ENTRY(50) + +Stub50__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 032h +Stub50__14nsXPTCStubBaseFv endp + +; 51 STUB_ENTRY(49) + +Stub49__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 031h +Stub49__14nsXPTCStubBaseFv endp + +; 50 STUB_ENTRY(48) + +Stub48__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 030h +Stub48__14nsXPTCStubBaseFv endp + +; 49 STUB_ENTRY(47) + +Stub47__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 02fh +Stub47__14nsXPTCStubBaseFv endp + +; 48 STUB_ENTRY(46) + +Stub46__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 02eh +Stub46__14nsXPTCStubBaseFv endp + +; 47 STUB_ENTRY(45) + +Stub45__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 02dh +Stub45__14nsXPTCStubBaseFv endp + +; 46 STUB_ENTRY(44) + +Stub44__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 02ch +Stub44__14nsXPTCStubBaseFv endp + +; 45 STUB_ENTRY(43) + +Stub43__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 02bh +Stub43__14nsXPTCStubBaseFv endp + +; 44 STUB_ENTRY(42) + +Stub42__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 02ah +Stub42__14nsXPTCStubBaseFv endp + +; 43 STUB_ENTRY(41) + +Stub41__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 029h +Stub41__14nsXPTCStubBaseFv endp + +; 42 STUB_ENTRY(40) + +Stub40__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 028h +Stub40__14nsXPTCStubBaseFv endp + +; 41 STUB_ENTRY(39) + +Stub39__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 027h +Stub39__14nsXPTCStubBaseFv endp + +; 40 STUB_ENTRY(38) + +Stub38__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 026h +Stub38__14nsXPTCStubBaseFv endp + +; 39 STUB_ENTRY(37) + +Stub37__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 025h +Stub37__14nsXPTCStubBaseFv endp + +; 38 STUB_ENTRY(36) + +Stub36__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 024h +Stub36__14nsXPTCStubBaseFv endp + +; 37 STUB_ENTRY(35) + +Stub35__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 023h +Stub35__14nsXPTCStubBaseFv endp + +; 36 STUB_ENTRY(34) + +Stub34__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 022h +Stub34__14nsXPTCStubBaseFv endp + +; 35 STUB_ENTRY(33) + +Stub33__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 021h +Stub33__14nsXPTCStubBaseFv endp + +; 34 STUB_ENTRY(32) + +Stub32__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 020h +Stub32__14nsXPTCStubBaseFv endp + +; 33 STUB_ENTRY(31) + +Stub31__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 01fh +Stub31__14nsXPTCStubBaseFv endp + +; 32 STUB_ENTRY(30) + +Stub30__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 01eh +Stub30__14nsXPTCStubBaseFv endp + +; 31 STUB_ENTRY(29) + +Stub29__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 01dh +Stub29__14nsXPTCStubBaseFv endp + +; 30 STUB_ENTRY(28) + +Stub28__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 01ch +Stub28__14nsXPTCStubBaseFv endp + +; 29 STUB_ENTRY(27) + +Stub27__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 01bh +Stub27__14nsXPTCStubBaseFv endp + +; 28 STUB_ENTRY(26) + +Stub26__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 01ah +Stub26__14nsXPTCStubBaseFv endp + +; 27 STUB_ENTRY(25) + +Stub25__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 019h +Stub25__14nsXPTCStubBaseFv endp + +; 26 STUB_ENTRY(24) + +Stub24__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 018h +Stub24__14nsXPTCStubBaseFv endp + +; 25 STUB_ENTRY(23) + +Stub23__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 017h +Stub23__14nsXPTCStubBaseFv endp + +; 24 STUB_ENTRY(22) + +Stub22__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 016h +Stub22__14nsXPTCStubBaseFv endp + +; 23 STUB_ENTRY(21) + +Stub21__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 015h +Stub21__14nsXPTCStubBaseFv endp + +; 22 STUB_ENTRY(20) + +Stub20__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 014h +Stub20__14nsXPTCStubBaseFv endp + +; 21 STUB_ENTRY(19) + +Stub19__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 013h +Stub19__14nsXPTCStubBaseFv endp + +; 20 STUB_ENTRY(18) + +Stub18__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 012h +Stub18__14nsXPTCStubBaseFv endp + +; 19 STUB_ENTRY(17) + +Stub17__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 011h +Stub17__14nsXPTCStubBaseFv endp + +; 18 STUB_ENTRY(16) + +Stub16__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 010h +Stub16__14nsXPTCStubBaseFv endp + +; 17 STUB_ENTRY(15) + +Stub15__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0fh +Stub15__14nsXPTCStubBaseFv endp + +; 16 STUB_ENTRY(14) + +Stub14__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0eh +Stub14__14nsXPTCStubBaseFv endp + +; 15 STUB_ENTRY(13) + +Stub13__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0dh +Stub13__14nsXPTCStubBaseFv endp + +; 14 STUB_ENTRY(12) + +Stub12__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0ch +Stub12__14nsXPTCStubBaseFv endp + +; 13 STUB_ENTRY(11) + +Stub11__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0bh +Stub11__14nsXPTCStubBaseFv endp + +; 12 STUB_ENTRY(10) + +Stub10__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 0ah +Stub10__14nsXPTCStubBaseFv endp + +; 11 STUB_ENTRY(9) + +Stub9__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 09h +Stub9__14nsXPTCStubBaseFv endp + +; 10 STUB_ENTRY(8) + +Stub8__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 08h +Stub8__14nsXPTCStubBaseFv endp + +; 9 STUB_ENTRY(7) + +Stub7__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 07h +Stub7__14nsXPTCStubBaseFv endp + +; 8 STUB_ENTRY(6) + +Stub6__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 06h +Stub6__14nsXPTCStubBaseFv endp + +; 7 STUB_ENTRY(5) + +Stub5__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 05h +Stub5__14nsXPTCStubBaseFv endp + +; 6 STUB_ENTRY(4) + +Stub4__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 04h +Stub4__14nsXPTCStubBaseFv endp + +; 5 STUB_ENTRY(3) + +Stub3__14nsXPTCStubBaseFv PROC OPTLINK EXPORT + setentidx 03h +Stub3__14nsXPTCStubBaseFv endp + + + END + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/.cvsignore new file mode 100644 index 00000000..055e647f --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/.cvsignore @@ -0,0 +1,2 @@ +Makefile +invoke_test diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/Makefile.in new file mode 100644 index 00000000..dbf0f64d --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/Makefile.in @@ -0,0 +1,50 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +CPPSRCS = stub_test.cpp #invoke_test.cpp +SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX)) + +include $(topsrcdir)/config/rules.mk + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/README b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/README new file mode 100644 index 00000000..04850b2e --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/README @@ -0,0 +1,6 @@ +These are just simple test programs in which stripped down versions of the +XPConnect invoke and stubs code can be built and tested as the code is brought +up on various platforms. These probrams do not test the param sizing and copying +functionality of the routines. However, they do supply a place where the lowest +level assembly language code can be developed and debugged in the simplest of +contexts before it is moved into the real routines.
\ No newline at end of file diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/clean.bat b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/clean.bat new file mode 100644 index 00000000..f320e222 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/clean.bat @@ -0,0 +1,5 @@ +@echo off +echo deleting intermediate files +if exist *.obj del *.obj > NUL +if exist *.ilk del *.ilk > NUL +if exist *.pdb del *.pdb > NUL
\ No newline at end of file diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/invoke_test.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/invoke_test.cpp new file mode 100644 index 00000000..376ba58f --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/invoke_test.cpp @@ -0,0 +1,239 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include <stdio.h> + +typedef unsigned nsresult; +typedef unsigned PRUint32; +typedef unsigned nsXPCVariant; + + +#if defined(WIN32) +#define NS_IMETHOD virtual nsresult __stdcall +#define NS_IMETHODIMP nsresult __stdcall +#else +#define NS_IMETHOD virtual nsresult +#define NS_IMETHODIMP nsresult +#endif + + +class base{ +public: + NS_IMETHOD ignored() = 0; +}; + +class foo : public base { +public: + NS_IMETHOD callme1(int i, int j) = 0; + NS_IMETHOD callme2(int i, int j) = 0; + NS_IMETHOD callme3(int i, int j) = 0; +}; + +class bar : public foo{ +public: + NS_IMETHOD ignored(); + NS_IMETHOD callme1(int i, int j); + NS_IMETHOD callme2(int i, int j); + NS_IMETHOD callme3(int i, int j); +}; + +/* +class baz : public base { +public: + NS_IMETHOD ignored(); + NS_IMETHOD callme1(); + NS_IMETHOD callme2(); + NS_IMETHOD callme3(); + void setfoo(foo* f) {other = f;} + + foo* other; +}; +NS_IMETHODIMP baz::ignored(){return 0;} +*/ + +NS_IMETHODIMP bar::ignored(){return 0;} + +NS_IMETHODIMP bar::callme1(int i, int j) +{ + printf("called bar::callme1 with: %d %d\n", i, j); + return 5; +} + +NS_IMETHODIMP bar::callme2(int i, int j) +{ + printf("called bar::callme2 with: %d %d\n", i, j); + return 5; +} + +NS_IMETHODIMP bar::callme3(int i, int j) +{ + printf("called bar::callme3 with: %d %d\n", i, j); + return 5; +} + +void docall(foo* f, int i, int j){ + f->callme1(i, j); +} + +/***************************************************************************/ +#if defined(WIN32) + +static PRUint32 __stdcall +invoke_count_words(PRUint32 paramCount, nsXPCVariant* s) +{ + return paramCount; +} + +static void __stdcall +invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPCVariant* s) +{ + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + *((PRUint32*)d) = *((PRUint32*)s); + } +} + +static nsresult __stdcall +DoInvoke(void* that, PRUint32 index, + PRUint32 paramCount, nsXPCVariant* params) +{ + __asm { + push params + push paramCount + call invoke_count_words // stdcall, result in eax + shl eax,2 // *= 4 + sub esp,eax // make space for params + mov edx,esp + push params + push paramCount + push edx + call invoke_copy_to_stack // stdcall + mov ecx,that // instance in ecx + push ecx // push this + mov edx,[ecx] // vtable in edx + mov eax,index + shl eax,2 // *= 4 + add edx,eax + call [edx] // stdcall, i.e. callee cleans up stack. + } +} + +#else +/***************************************************************************/ +// just Linux_x86 now. Add other later... + +static PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPCVariant* s) +{ + return paramCount; +} + +static void +invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPCVariant* s) +{ + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + *((PRUint32*)d) = *((PRUint32*)s); + } +} + +static nsresult +DoInvoke(void* that, PRUint32 index, + PRUint32 paramCount, nsXPCVariant* params) +{ + PRUint32 result; + void* fn_count = invoke_count_words; + void* fn_copy = invoke_copy_to_stack; + + __asm__ __volatile__( + "pushl %4\n\t" + "pushl %3\n\t" + "movl %5, %%eax\n\t" + "call *%%eax\n\t" /* count words */ + "addl $0x8, %%esp\n\t" + "shl $2, %%eax\n\t" /* *= 4 */ + "subl %%eax, %%esp\n\t" /* make room for params */ + "movl %%esp, %%edx\n\t" + "pushl %4\n\t" + "pushl %3\n\t" + "pushl %%edx\n\t" + "movl %6, %%eax\n\t" + "call *%%eax\n\t" /* copy params */ + "addl $0xc, %%esp\n\t" + "movl %1, %%ecx\n\t" + "pushl %%ecx\n\t" + "movl (%%ecx), %%edx\n\t" + "movl %2, %%eax\n\t" /* function index */ + "shl $2, %%eax\n\t" /* *= 4 */ + "addl $8, %%eax\n\t" /* += 8 */ + "addl %%eax, %%edx\n\t" + "call *(%%edx)\n\t" /* safe to not cleanup esp */ + "movl %%eax, %0" + : "=g" (result) /* %0 */ + : "g" (that), /* %1 */ + "g" (index), /* %2 */ + "g" (paramCount), /* %3 */ + "g" (params), /* %4 */ + "g" (fn_count), /* %5 */ + "g" (fn_copy) /* %6 */ + : "ax", "cx", "dx", "memory" + ); + + return result; +} + +#endif +/***************************************************************************/ + +int main() +{ + nsXPCVariant params1[2] = {1,2}; + nsXPCVariant params2[2] = {2,4}; + nsXPCVariant params3[2] = {3,6}; + + foo* a = new bar(); + +// printf("calling via C++...\n"); +// docall(a, 12, 24); + + printf("calling via ASM...\n"); + DoInvoke(a, 1, 2, params1); + DoInvoke(a, 2, 2, params2); + DoInvoke(a, 3, 2, params3); + + return 0; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/mk_invoke.bat b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/mk_invoke.bat new file mode 100644 index 00000000..10a9be51 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/mk_invoke.bat @@ -0,0 +1,9 @@ +@echo off +@echo deleing old output +if exist invoke_test.obj del invoke_test.obj > NUL +if exist invoke_test.ilk del invoke_test.ilk > NUL +if exist *.pdb del *.pdb > NUL +if exist invoke_test.exe del invoke_test.exe > NUL + +@echo building... +cl /nologo -Zi -DWIN32 invoke_test.cpp
\ No newline at end of file diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/mk_stub.bat b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/mk_stub.bat new file mode 100644 index 00000000..f9af17af --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/mk_stub.bat @@ -0,0 +1,9 @@ +@echo off +@echo deleing old output +if exist stub_test.obj del stub_test.obj > NUL +if exist stub_test.ilk del stub_test.ilk > NUL +if exist *.pdb del *.pdb > NUL +if exist stub_test.exe del stub_test.exe > NUL + +@echo building... +cl /nologo -Zi -DWIN32 stub_test.cpp
\ No newline at end of file diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/stub_test.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/stub_test.cpp new file mode 100644 index 00000000..10935299 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/test/stub_test.cpp @@ -0,0 +1,210 @@ + +#include <stdio.h> + +typedef unsigned nsresult; +typedef unsigned PRUint32; +typedef unsigned nsXPCVariant; + + +#if defined(WIN32) +#define NS_IMETHOD virtual nsresult __stdcall +#define NS_IMETHODIMP nsresult __stdcall +#else +#define NS_IMETHOD virtual nsresult +#define NS_IMETHODIMP nsresult +#endif + + +class base{ +public: + NS_IMETHOD ignored() = 0; +}; + +class foo : public base { +public: + NS_IMETHOD callme1(int i, int j) = 0; + NS_IMETHOD callme2(int i, int j) = 0; + NS_IMETHOD callme3(int i, int j) = 0; +}; + +class bar : public foo{ +public: + NS_IMETHOD ignored(); + NS_IMETHOD callme1(int i, int j); + NS_IMETHOD callme2(int i, int j); + NS_IMETHOD callme3(int i, int j); +}; + +class baz : public base { +public: + NS_IMETHOD ignored(); + NS_IMETHOD callme1(); + NS_IMETHOD callme2(); + NS_IMETHOD callme3(); + void setfoo(foo* f) {other = f;} + + foo* other; +}; +NS_IMETHODIMP baz::ignored(){return 0;} + +NS_IMETHODIMP bar::ignored(){return 0;} + +NS_IMETHODIMP bar::callme1(int i, int j) +{ + printf("called bar::callme1 with: %d %d\n", i, j); + return 15; +} + +NS_IMETHODIMP bar::callme2(int i, int j) +{ + printf("called bar::callme2 with: %d %d\n", i, j); + return 25; +} + +NS_IMETHODIMP bar::callme3(int i, int j) +{ + printf("called bar::callme3 with: %d %d\n", i, j); + return 35; +} + +void docall(foo* f, int i, int j){ + f->callme1(i, j); +} + +/***************************************************************************/ +#if defined(WIN32) + +static int __stdcall +PrepareAndDispatch(baz* self, PRUint32 methodIndex, + PRUint32* args, PRUint32* stackBytesToPop) +{ + fprintf(stdout, "PrepareAndDispatch (%p, %d, %p)\n", + (void*)self, methodIndex, (void*)args); + foo* a = self->other; + int p1 = (int) *args; + int p2 = (int) *(args+1); + int out = 0; + switch(methodIndex) + { + case 1: out = a->callme1(p1, p2); break; + case 2: out = a->callme2(p1, p2); break; + case 3: out = a->callme3(p1, p2); break; + } + *stackBytesToPop = 2*4; + return out; +} + +#ifndef __GNUC__ +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 ecx, [ebp+16] // pointer to args + push ecx + mov edx, [ebp+4] // vtbl_index + push edx + mov eax, [ebp+12] // this + push eax + call PrepareAndDispatch + mov edx, [ebp+8] // return address + mov ecx, [ebp-4] // stackBytesToPop + add ecx, 12 // for this, the index, and ret 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 baz::callme##n() \ +{ __asm push n __asm jmp SharedStub } + +#else /* __GNUC__ */ + +#define STUB_ENTRY(n) \ +nsresult __stdcall baz::callme##n() \ +{ \ + PRUint32 *args, stackBytesToPop; \ + int result = 0; \ + baz *obj; \ + __asm__ __volatile__ ( \ + "leal 0x0c(%%ebp), %0\n\t" /* args */ \ + "movl 0x08(%%ebp), %1\n\t" /* this */ \ + : "=r" (args), \ + "=r" (obj)); \ + result = PrepareAndDispatch(obj, n, args,&stackBytesToPop); \ + fprintf(stdout, "stub returning: %d\n", result); \ + fprintf(stdout, "bytes to pop: %d\n", stackBytesToPop); \ + return result; \ +} + +#endif /* ! __GNUC__ */ + +#else +/***************************************************************************/ +// just Linux_x86 now. Add other later... + +static int +PrepareAndDispatch(baz* self, PRUint32 methodIndex, PRUint32* args) +{ + foo* a = self->other; + int p1 = (int) *args; + int p2 = (int) *(args+1); + switch(methodIndex) + { + case 1: a->callme1(p1, p2); break; + case 2: a->callme2(p1, p2); break; + case 3: a->callme3(p1, p2); break; + } + return 1; +} + +#define STUB_ENTRY(n) \ +nsresult baz::callme##n() \ +{ \ + register void* method = PrepareAndDispatch; \ + register nsresult result; \ + __asm__ __volatile__( \ + "leal 0x0c(%%ebp), %%ecx\n\t" /* args */ \ + "pushl %%ecx\n\t" \ + "pushl $"#n"\n\t" /* method index */ \ + "movl 0x08(%%ebp), %%ecx\n\t" /* this */ \ + "pushl %%ecx\n\t" \ + "call *%%edx" /* PrepareAndDispatch */ \ + : "=a" (result) /* %0 */ \ + : "d" (method) /* %1 */ \ + : "memory" ); \ + return result; \ +} + +#endif +/***************************************************************************/ + +STUB_ENTRY(1) +STUB_ENTRY(2) +STUB_ENTRY(3) + +int main() +{ + foo* a = new bar(); + baz* b = new baz(); + + /* here we make the global 'check for alloc failure' checker happy */ + if(!a || !b) + return 1; + + foo* c = (foo*)b; + + b->setfoo(a); + c->callme1(1,2); + c->callme2(2,4); + c->callme3(3,6); + + return 0; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/.cvsignore new file mode 100644 index 00000000..ff6fd9bc --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/.cvsignore @@ -0,0 +1,2 @@ +Makefile +xptcstubs_asm_mips.s diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/Makefile.in new file mode 100644 index 00000000..78bf1f92 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/Makefile.in @@ -0,0 +1,416 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +LIBRARY_NAME = xptcmd + +# +# The default is this buildable, but non-functioning code. +# +CPPSRCS := xptcinvoke_unsupported.cpp xptcstubs_unsupported.cpp + +# Force use of PIC +FORCE_USE_PIC = 1 + +include $(topsrcdir)/config/config.mk + +###################################################################### +# i386 and beyond +###################################################################### +# +# Lots of Unixish x86 flavors +# +ifneq (,$(filter FreeBSD NetBSD OpenBSD BSD_OS Darwin,$(OS_ARCH))) +ifeq (86,$(findstring 86,$(OS_TEST))) +CPPSRCS := xptcinvoke_unixish_x86.cpp xptcstubs_unixish_x86.cpp +endif +endif +# +# New code for Linux, et. al., with gcc +# Migrate other platforms here after testing +# +ifneq (,$(filter Linux,$(OS_ARCH))) +# Linux/x86-64 +ifeq (x86_64,$(OS_TEST)) +CPPSRCS := xptcinvoke_x86_64_linux.cpp xptcstubs_x86_64_linux.cpp +else +ifeq (86,$(findstring 86,$(OS_TEST))) +CPPSRCS := xptcinvoke_gcc_x86_unix.cpp xptcstubs_gcc_x86_unix.cpp +endif +endif +endif +# IA64 Linux +ifneq (,$(filter Linux,$(OS_ARCH))) +ifneq (,$(findstring ia64,$(OS_TEST))) +CPPSRCS := xptcinvoke_ipf64.cpp xptcstubs_ipf64.cpp +ASFILES := xptcstubs_asm_ipf64.s xptcinvoke_asm_ipf64.s +endif +endif +# +# BeOS/Intel (uses the same unixish_x86 code) +# +ifeq ($(OS_ARCH)$(OS_TEST),BeOSBePC) +CPPSRCS := xptcinvoke_unixish_x86.cpp xptcstubs_unixish_x86.cpp +endif +# +# Neutrino/Intel (uses the same unixish_x86 code) +# +ifeq ($(OS_TARGET)$(OS_TEST),NTOx86) +CPPSRCS := xptcinvoke_unixish_x86.cpp xptcstubs_unixish_x86.cpp +endif + +###################################################################### +# Solaris/Intel +###################################################################### +# +# Solaris/Intel +# +ifeq ($(OS_ARCH),SunOS) +ifeq ($(OS_TEST),i86pc) +CPPSRCS := xptcinvoke_x86_solaris.cpp xptcstubs_x86_solaris.cpp +# 28817: if Solaris Intel OS, and native compiler, always build optimised. +ifndef GNU_CC +CXXFLAGS += -O +endif +endif +endif + +###################################################################### +# Alpha +###################################################################### +# +# Tru64/Alpha +# +ifeq ($(OS_ARCH)$(OS_TEST),OSF1alpha) +CPPSRCS := xptcinvoke_osf1_alpha.cpp xptcstubs_osf1_alpha.cpp +ASFILES := xptcinvoke_asm_osf1_alpha.s xptcstubs_asm_osf1_alpha.s +endif +# +# Linux/Alpha +# +ifneq (,$(filter Linuxalpha FreeBSDalpha NetBSDalpha,$(OS_ARCH)$(OS_TEST))) +CPPSRCS := xptcinvoke_linux_alpha.cpp xptcstubs_linux_alpha.cpp +endif +# +# OpenVMS/Alpha +# +ifeq ($(OS_ARCH)$(CPU_ARCH),OpenVMSAlpha) +CPPSRCS := xptcinvoke_openvms_alpha.cpp xptcstubs_openvms_alpha.cpp +ASFILES := xptcinvoke_asm_openvms_alpha.s xptcstubs_asm_openvms_alpha.s +endif + +###################################################################### +# ARM +###################################################################### +# +# Linux/ARM +# +ifeq ($(OS_ARCH),Linux) +ifneq (,$(filter arm% sa110,$(OS_TEST))) +CPPSRCS := xptcinvoke_arm.cpp xptcstubs_arm.cpp +CXXFLAGS += -O2 +endif +endif +# +# NetBSD/ARM +# +ifeq ($(OS_ARCH),NetBSD) +ifneq (,$(filter arm% sa110,$(OS_TEST))) +CPPSRCS := xptcinvoke_arm_netbsd.cpp xptcstubs_arm_netbsd.cpp +endif +endif + +###################################################################### +# HPPA +###################################################################### +# +# HP-UX/PA32 +# +# for gas and gcc, check comment in xptcinvoke_asm_pa32.s +ifeq ($(OS_ARCH),HP-UX) +ifneq ($(CC),gcc) +ifneq ($(OS_TEST),ia64) +CPPSRCS := xptcinvoke_pa32.cpp xptcstubs_pa32.cpp +ASFILES := xptcstubs_asm_pa32.s xptcinvoke_asm_pa32.s +else +CPPSRCS := xptcinvoke_ipf32.cpp xptcstubs_ipf32.cpp +ASFILES := xptcstubs_asm_ipf32.s xptcinvoke_asm_ipf32.s +endif + +# #18875 Building the CPP's (CXX) optimized causes a crash +CXXFLAGS := $(filter-out $(MOZ_OPTIMIZE_FLAGS), $(CXXFLAGS)) +endif +endif + +###################################################################### +# M68k +###################################################################### +# +# NetBSD/m68k +# +ifeq ($(OS_ARCH),NetBSD) +ifneq (,$(filter amiga atari hp300 mac68k mvme68k next68k sun3 sun3x x68k,$(OS_TEST))) +CPPSRCS := xptcinvoke_netbsd_m68k.cpp xptcstubs_netbsd_m68k.cpp +endif +endif + +# +# Linux/m68k +# +ifeq ($(OS_ARCH),Linux) +ifeq ($(OS_TEST),m68k) +CPPSRCS := xptcinvoke_linux_m68k.cpp xptcstubs_linux_m68k.cpp +endif +endif + +###################################################################### +# MIPS +###################################################################### +# +# IRIX/MIPS +# +ifeq ($(OS_ARCH),IRIX) +ifneq ($(basename $(OS_RELEASE)),5) +CPPSRCS := xptcinvoke_irix.cpp xptcstubs_irix.cpp +ASFILES := xptcinvoke_asm_irix.s xptcstubs_asm_irix.s +ifdef GNU_CC +ASFLAGS += -Wa,-D__GNUC__ +else +CXXFLAGS := $(shell echo $(CXXFLAGS) | sed 's/-O\(3\|fast\)/-O2/g') +endif +endif +endif + +ifeq ($(OS_ARCH),Linux) +ifneq (,$(findstring mips, $(OS_TEST))) +CPPSRCS := xptcinvoke_mips.cpp xptcstubs_mips.cpp +ASFILES := xptcinvoke_asm_mips.s xptcstubs_asm_mips.s +#xptcstubs_mips.cpp +# xptcstubs_asm_mips.s +ifdef GNU_CC +ASFLAGS += $(INCLUDES) -x assembler-with-cpp -D__GNUC__ +endif +endif +endif + +###################################################################### +# PowerPC +###################################################################### +# +# AIX/PPC +# +ifeq ($(OS_ARCH),AIX) +ifdef HAVE_64BIT_OS +CPPSRCS := xptcinvoke_ppc_aix64.cpp xptcstubs_ppc_aix64.cpp +ASFILES := xptcinvoke_asm_ppc_aix64.s xptcstubs_asm_ppc_aix64.s +else +ifeq ($(AIX_OBJMODEL),ibm) +CPPSRCS := xptcinvoke_ppc_aix.cpp xptcstubs_ppc_aix.cpp +ASFILES := xptcinvoke_asm_ppc_ibmobj_aix.s xptcstubs_asm_ppc_aix.s +else +CPPSRCS := xptcinvoke_ppc_aix.cpp xptcstubs_ppc_aix.cpp +ASFILES := xptcinvoke_asm_ppc_aix.s xptcstubs_asm_ppc_aix.s +endif +endif + +# #24617 Building the CPP's (CXX) optimized causes a crash +CXXFLAGS := $(filter-out $(MOZ_OPTIMIZE_FLAGS), $(CXXFLAGS)) +endif + +# +# Linux/PPC +# +ifeq ($(OS_ARCH)$(OS_TEST),Linuxppc) +CPPSRCS := xptcinvoke_ppc_linux.cpp xptcstubs_ppc_linux.cpp +ASFILES := xptcinvoke_asm_ppc_linux.s xptcstubs_asm_ppc_linux.s +AS := $(CC) -c -x assembler-with-cpp +endif + +# +# NetBSD/PPC +# +ifneq (,$(filter NetBSDmacppc NetBSDbebox NetBSDofppc NetBSDprep NetBSDamigappc,$(OS_ARCH)$(OS_TEST))) +CPPSRCS := xptcinvoke_ppc_netbsd.cpp xptcstubs_ppc_netbsd.cpp +ASFILES := xptcinvoke_asm_ppc_netbsd.s xptcstubs_asm_ppc_netbsd.s +endif + +# +# Darwin/PPC +# +ifeq ($(OS_ARCH),Darwin) +ifeq ($(TARGET_CPU), powerpc) +ASFLAGS += -x assembler-with-cpp # assumes $(AS) == $(CC) +ifdef HAVE_GCC3_ABI +ASFLAGS += -DHAVE_GCC3_ABI +endif +CPPSRCS := xptcinvoke_ppc_rhapsody.cpp xptcstubs_ppc_rhapsody.cpp +ASFILES := xptcinvoke_asm_ppc_rhapsody.s xptcstubs_asm_ppc_darwin.s +endif +endif + +###################################################################### +# SPARC +###################################################################### +# +# BSD_OS/SPARC +# +ifeq ($(OS_ARCH),BSD_OS) +ifneq (,$(findstring sparc,$(OS_TEST))) +CPPSRCS := xptcinvoke_sparc_solaris.cpp xptcstubs_sparc_solaris.cpp +ASFILES := xptcinvoke_asm_sparc_bsdos.s xptcstubs_asm_sparc_solaris.s +endif +endif +# +# Linux/SPARC +# +ifeq ($(OS_ARCH),Linux) +ifneq (,$(findstring sparc,$(OS_TEST))) +CPPSRCS := xptcinvoke_sparc_solaris.cpp xptcstubs_sparc_solaris.cpp +ifdef HAVE_GCC3_ABI +ASFILES := xptcinvoke_asm_sparc_linux_GCC3.s xptcstubs_asm_sparc_solaris.s +else +ASFILES := xptcinvoke_asm_sparc_linux.s xptcstubs_asm_sparc_solaris.s +endif +endif +endif +# +# NetBSD/SPARC +# +ifeq ($(OS_ARCH)$(OS_TEST),NetBSDsparc) +CPPSRCS := xptcinvoke_sparc_netbsd.cpp xptcstubs_sparc_netbsd.cpp +ASFILES := xptcinvoke_asm_sparc_netbsd.s xptcstubs_asm_sparc_netbsd.s +endif +# +# Solaris/SPARC +# +ifeq ($(OS_ARCH),SunOS) +ifneq (86,$(findstring 86,$(OS_TEST))) +ifdef HAVE_64BIT_OS +CPPSRCS := xptcinvoke_sparcv9_solaris.cpp xptcstubs_sparcv9_solaris.cpp +else +CPPSRCS := xptcinvoke_sparc_solaris.cpp xptcstubs_sparc_solaris.cpp +endif + +ifeq ($(GNU_CC),1) +ifdef HAVE_GCC3_ABI +ASFILES := xptcinvoke_asm_sparc_solaris_GCC3.s xptcstubs_asm_sparc_solaris.s +else +ASFILES := xptcinvoke_asm_sparc_solaris_GCC.s xptcstubs_asm_sparc_solaris.s +endif +else +ifdef HAVE_64BIT_OS +ASFILES := xptcinvoke_asm_sparcv9_solaris_SUNW.s xptcstubs_asm_sparcv9_solaris.s +else +ASFILES := xptcinvoke_asm_sparc_solaris_SUNW.s xptcstubs_asm_sparc_solaris.s +endif +endif + +endif +endif + +###################################################################### +# S/390 +###################################################################### +# +# Linux for S/390 +# +ifeq ($(OS_ARCH)$(OS_TEST),Linuxs390) +CPPSRCS := xptcinvoke_linux_s390.cpp xptcstubs_linux_s390.cpp +endif + +ifeq ($(OS_ARCH)$(OS_TEST),Linuxs390x) +CPPSRCS := xptcinvoke_linux_s390x.cpp xptcstubs_linux_s390x.cpp +endif + + +# we don't want the shared lib, but we want to force the creation of a static lib. +FORCE_STATIC_LIB = 1 + +include $(topsrcdir)/config/rules.mk + +DEFINES += -DEXPORT_XPTC_API + +INCLUDES += -I$(srcdir)/../.. + +ifeq ($(OS_ARCH),Linux) +ifneq (,$(findstring mips, $(OS_TEST))) +xptcstubs_asm_mips.o: xptcstubs_asm_mips.s.m4 $(PUBLIC)/xptcstubsdef.inc + m4 $(INCLUDES) $< > ./xptcstubs_asm_mips.s && \ + $(AS) -o $@ $(ASFLAGS) $(AS_DASH_C_FLAG) ./xptcstubs_asm_mips.s + $(RM) -f ./xptcstubs_asm_mips.s +endif +endif + +ifeq ($(OS_ARCH),Darwin) +xptcstubs_asm_ppc_darwin.o: xptcstubs_asm_ppc_darwin.s.m4 $(PUBLIC)/xptcstubsdef.inc Makefile + gm4 $(INCLUDES) $< > ./xptcstubs_asm_ppc_darwin.s && \ + $(AS) -o $@ $(ASFLAGS) $(AS_DASH_C_FLAG) ./xptcstubs_asm_ppc_darwin.s + $(RM) -f ./xptcstubs_asm_ppc_darwin.s +endif + +ifeq ($(OS_ARCH),IRIX) +# The assembler on IRIX (6.3 only?) seems to have trouble with the default command, +# but works fine if we first copy the header and source file into the current dir. +xptcstubs_asm_irix.o: $(PUBLIC)/xptcstubsdef.inc $(srcdir)/xptcstubs_asm_irix.s + @rm -f ./xptcstubsdef.inc + @cp $(PUBLIC)/xptcstubsdef.inc . + @if test ! -f ./Makefile.in; then rm -f ./xptcstubs_asm_irix.s; cp $(srcdir)/xptcstubs_asm_irix.s .; else true; fi + $(AS) -o $@ $(ASFLAGS) $(AS_DASH_C_FLAG) ./xptcstubs_asm_irix.s + @rm -f ./xptcstubsdef.inc + @if test ! -f ./Makefile.in; then rm -f ./xptcstubs_asm_irix.s; else true; fi +endif + +ifeq ($(OS_ARCH),OpenVMS) +# Our assembler wants the include file to be of assembler syntax, not C/C++ +# syntax, so we have to massage it slightly. + +xptcstubs_asm_openvms_alpha.o: $(PUBLIC)/xptcstubsdef.inc $(srcdir)/xptcstubs_asm_openvms_alpha.s + sed \ + -e 's/^\(.*_ENTRY\)(\([0-9]*\))/ \1 \2/' \ + -e 's/\/\*\(.*\)\*\//; \1/' \ + $(PUBLIC)/xptcstubsdef.inc > ./xptcstubsdef_asm.vms + $(AS) -o $@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(srcdir)/xptcstubs_asm_openvms_alpha.s + @rm -f ./xptcstubsdef_asm.vms +endif + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/Makefile.kup b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/Makefile.kup new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/Makefile.kup diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/vtable_layout_x86.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/vtable_layout_x86.cpp new file mode 100644 index 00000000..912f50e4 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/vtable_layout_x86.cpp @@ -0,0 +1,62 @@ +/* this code contributed by Bert Driehuis <bert_driehuis@nl.compuware.com> */ + +#include <stdio.h> + +// Try to determine the vtable layout generated by G++ +// Produces the offset at which the first vtable entry can be +// found, and the factor to apply for subsequent entries on stdout. +// Example output: +// #define GCC_VTABLE_START 0xc +// #define GCC_VTABLE_FACTOR 0x8 + +class test { +public: + virtual int t1(void); + virtual int t2(void); + int x; +}; + +test::test() { this->x = 0x12121212; }; + +int test::t1(void) { return 1; } +int test::t2(void) { return 2; } + +void die(char *x) { + fprintf(stderr, "%s\n", x); + exit(1); +} + +int +main() +{ + int i; + test *t = new test(); + int *tp = (int *) t; + int off1 = -1; + int off2 = -1; + int factor; + int factorshift; + + if (*tp++ != 0x12121212) + die("Integer element test::x not found!"); + tp = (int *) *tp; + for (i = 0; i < 10; i++) { + if (tp[i] == (int) t->t1) + off1 = i; + if (tp[i] == (int) t->t2) + off2 = i; + } + if (off1 == -1 || off2 == -1) + die("Could not determine offset into vtable!"); + factor = (off2 - off1) * 4; + factorshift = -1; + while (factor) { + factorshift++; + factor >>= 1; + } + printf("/* Automatically generated by vtable_layout_x86.cpp */\n"); + printf("#define GCC_VTABLE_START\t0x%x\n", off1 * 4); + printf("#define GCC_VTABLE_FACTOR\t0x%x\n", (off2 - off1) * 4); + printf("#define GCC_VTABLE_SHIFT\t0x%x\n", factorshift); + exit(0); +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h new file mode 100644 index 00000000..707352aa --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h @@ -0,0 +1,92 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Special include file for xptc*_gcc_x86_unix.cpp */ + +// +// this may improve the static function calls, but may not. +// + +// #define MOZ_USE_STDCALL + +#ifdef MOZ_USE_STDCALL +#define ATTRIBUTE_STDCALL __attribute__ ((__stdcall__)) +#else +#define ATTRIBUTE_STDCALL +#endif + +#ifdef MOZ_NEED_LEADING_UNDERSCORE +#define SYMBOL_UNDERSCORE "_" +#else +#define SYMBOL_UNDERSCORE +#endif + +/* + What are those keeper functions? + + The problem: gcc doesn't know that the assembler routines call + static functions so gcc may not emit the definition (i.e., the + code) for these functions. In gcc 3.1 and up + "__attribute__ ((used))" exists and solves the problem. + For older gcc versions it's not so easy. One could use the + -fkeep-inline-functions but that keeps a surprising number of + functions which bloats the compiled library. It seems otherwise + harmless, though. Alternatively, one could use + -fno-inline-functions which works right now but might cause a + slowdown under some circumstances. The problem with these methods + is that they do not automatically adapt to the compiler used. + + The best solution seems to be to create dummy functions that + reference the appropriate static functions. It's then necessary + to "use" these functions in a way that gcc will not optimize + away. The keeper functions use assembly code to confuse gcc. + + One drawback is that the keeper functions are externally visible + so they shouldn't do anything harmful. + + With the right linker, one could make the keeper functions local + so they wouldn't be visible. + */ + + +// gcc 3.1 and up +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define ATTRIBUTE_USED __attribute__ ((__used__)) +#else +#define ATTRIBUTE_USED +#endif + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptc_platforms_unixish_x86.h b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptc_platforms_unixish_x86.h new file mode 100644 index 00000000..23eb23ee --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptc_platforms_unixish_x86.h @@ -0,0 +1,161 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific #defines to be shared by the various platforms sharing +* the unixish_86 code +*/ + +/* +* The goal here is to clearly define the binary compatibility parameters for +* the platforms that will use this code. Rather than switch at compile time +* based on the compiler that happens to be in use we are forcing implementors +* to make a conscious decision. +* +* For some of these platforms the community may choose to have more than one +* binary model in effect. In that case I suggest that there be explicit sub +* defines for that platform specifying 'TYPE1', 'TYPE2', etc. The decision on +* which 'TYPE' to use would be triggered by a setting passed through from the +* config system. +* +* For example we might end up with something like: +* +* #elif defined(NTO) +* # if defined(TYPE1) +* # define CFRONT_STYLE_THIS_ADJUST +* # elif defined(TYPE1) +* # define THUNK_BASED_THIS_ADJUST +* # else +* # error "need TYPE1 or TYPE2 for NTO" +* # endif +* #elif defined(__BEOS__) +* +* and so on.... +* +*/ + +#if defined(LINUX) + +#if (__GNUC__ == 2) && (__GNUC_MINOR__ <= 7) +/* Old gcc 2.7.x.x. What does gcc 2.8.x do?? */ +#define CFRONT_STYLE_THIS_ADJUST +#else +/* egcs and later */ +#define THUNK_BASED_THIS_ADJUST +#endif + +#elif defined(__FreeBSD__) +/* System versions of gcc on FreeBSD don't use thunks. On 3.x, the system + * compiler is gcc 2.7.2.3, which doesn't use thunks by default. On 4.x and + * 5.x, /usr/src/contrib/gcc/config/freebsd.h explicitly undef's + * DEFAULT_VTABLE_THUNKS. (The one exception is a brief period (September + * 1999 - Jan 2000) during 4.0-CURRENT, after egcs was merged -- + * this was changed before 4.0-RELEASE, but we can handle it anyway.) + * + * Versions of gcc from the ports collection (/usr/ports/lang/egcs), + * however, have DEFAULT_VTABLE_THUNKS #defined to 1, at least + * in all ports collections since the 2.95 merge. (Supporting optional + * compilers from FreeBSD 3.2 or earlier seems unnecessary). + * + * The easiest way to distinguish the ports collection gcc from the system + * gcc is that the system gcc defines __FreeBSD_cc_version. This variable + * can also identify versions that use thunks. This includes some 4.x versions + * and now newer 5.x versions. + */ +#if defined(__FreeBSD_cc_version) && \ + (__FreeBSD_cc_version < 500003) && \ + (__FreeBSD_cc_version < 400002 || __FreeBSD_cc_version > 400003) +#define CFRONT_STYLE_THIS_ADJUST +#else +#define THUNK_BASED_THIS_ADJUST +#endif + +#elif defined(__NetBSD__) +#define THUNK_BASED_THIS_ADJUST + +#elif defined(__OpenBSD__) +/* OpenBSD instroduces GCC 2.95.x in late May 1999 */ +#include <sys/param.h> +#if OpenBSD <= 199905 +#define THUNK_BASED_THIS_ADJUST +#else +#define CFRONT_STYLE_THIS_ADJUST +#endif + +#elif defined(__bsdi__) +#include <sys/param.h> +#if _BSDI_VERSION >= 199910 +/* BSDI/4.1 ships with egcs, ergo thunk-based */ +#define THUNK_BASED_THIS_ADJUST +#else +#define CFRONT_STYLE_THIS_ADJUST +#endif + +#elif defined(NTO) +#define CFRONT_STYLE_THIS_ADJUST + +#elif defined(__BEOS__) +#define CFRONT_STYLE_THIS_ADJUST + +#elif defined(__sun__) || defined(__sun) +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ +#define THUNK_BASED_THIS_ADJUST +#else +#define CFRONT_STYLE_THIS_ADJUST +#endif + +#elif defined(_WIN32) +#define THUNK_BASED_THIS_ADJUST + +#elif defined(__EMX__) +#define THUNK_BASED_THIS_ADJUST + +#elif defined (__APPLE__) && (__MACH__) +#define THUNK_BASED_THIS_ADJUST + +#else +#error "need a platform define if using unixish x86 code" +#endif + +/***************************************************************************/ + +#if !defined(THUNK_BASED_THIS_ADJUST) && !defined(CFRONT_STYLE_THIS_ADJUST) +#error "need to define 'this' adjust scheme" +#endif + +#if defined(THUNK_BASED_THIS_ADJUST) && defined(CFRONT_STYLE_THIS_ADJUST) +#error "need to define only ONE 'this' adjust scheme" +#endif diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_amd64_darwin.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_amd64_darwin.cpp new file mode 100644 index 00000000..af2919d8 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_amd64_darwin.cpp @@ -0,0 +1,218 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org Code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Platform specific code to invoke XPCOM methods on native objects + +#include "xptcprivate.h" + +// 6 integral parameters are passed in registers +const PRUint32 GPR_COUNT = 6; + +// 8 floating point parameters are passed in SSE registers +const PRUint32 FPR_COUNT = 8; + +// Remember that these 'words' are 64-bit long +static inline void +invoke_count_words(PRUint32 paramCount, nsXPTCVariant * s, + PRUint32 & nr_gpr, PRUint32 & nr_fpr, PRUint32 & nr_stack) +{ + nr_gpr = 1; // skip one GP register for 'that' + nr_fpr = 0; + nr_stack = 0; + + /* Compute number of eightbytes of class MEMORY. */ + for (uint32 i = 0; i < paramCount; i++, s++) { + if (!s->IsPtrData() + && (s->type == nsXPTType::T_FLOAT || s->type == nsXPTType::T_DOUBLE)) { + if (nr_fpr < FPR_COUNT) + nr_fpr++; + else + nr_stack++; + } + else { + if (nr_gpr < GPR_COUNT) + nr_gpr++; + else + nr_stack++; + } + } +} + +static void +invoke_copy_to_stack(PRUint64 * d, PRUint32 paramCount, nsXPTCVariant * s, + PRUint64 * gpregs, double * fpregs) +{ + PRUint32 nr_gpr = 1; // skip one GP register for 'that' + PRUint32 nr_fpr = 0; + PRUint64 value; + + for (uint32 i = 0; i < paramCount; i++, s++) { + if (s->IsPtrData()) + value = (PRUint64) s->ptr; + else { + switch (s->type) { + case nsXPTType::T_FLOAT: break; + case nsXPTType::T_DOUBLE: break; + case nsXPTType::T_I8: value = s->val.i8; break; + case nsXPTType::T_I16: value = s->val.i16; break; + case nsXPTType::T_I32: value = s->val.i32; break; + case nsXPTType::T_I64: value = s->val.i64; break; + case nsXPTType::T_U8: value = s->val.u8; break; + case nsXPTType::T_U16: value = s->val.u16; break; + case nsXPTType::T_U32: value = s->val.u32; break; + case nsXPTType::T_U64: value = s->val.u64; break; + case nsXPTType::T_BOOL: value = s->val.b; break; + case nsXPTType::T_CHAR: value = s->val.c; break; + case nsXPTType::T_WCHAR: value = s->val.wc; break; + default: value = (PRUint64) s->val.p; break; + } + } + + if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) { + if (nr_fpr < FPR_COUNT) + fpregs[nr_fpr++] = s->val.d; + else { + *((double *)d) = s->val.d; + d++; + } + } + else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) { + if (nr_fpr < 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. + fpregs[nr_fpr++] = s->val.d; + else { + *((float *)d) = s->val.f; + d++; + } + } + else { + if (nr_gpr < GPR_COUNT) + gpregs[nr_gpr++] = value; + else + *d++ = value; + } + } +} + +extern "C" +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports * that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant * params) +{ + PRUint32 nr_gpr, nr_fpr, nr_stack; + invoke_count_words(paramCount, params, nr_gpr, nr_fpr, nr_stack); + + // Stack, if used, must be 16-bytes aligned + if (nr_stack) + nr_stack = (nr_stack + 1) & ~1; + + // Load parameters to stack, if necessary + PRUint64 *stack = (PRUint64 *) __builtin_alloca(nr_stack * 8); + PRUint64 gpregs[GPR_COUNT]; + double fpregs[FPR_COUNT]; + invoke_copy_to_stack(stack, paramCount, params, gpregs, fpregs); + + // disable the warning about sometimes not initialized variables which is hit + // when we pass less than 8 XMM or less than 6 GPR registers. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wsometimes-uninitialized" + + // Load FPR registers from fpregs[] + register double d0 asm("xmm0"); + register double d1 asm("xmm1"); + register double d2 asm("xmm2"); + register double d3 asm("xmm3"); + register double d4 asm("xmm4"); + register double d5 asm("xmm5"); + register double d6 asm("xmm6"); + register double d7 asm("xmm7"); + + switch (nr_fpr) { +#define ARG_FPR(N) \ + case N+1: d##N = fpregs[N]; + ARG_FPR(7); + ARG_FPR(6); + ARG_FPR(5); + ARG_FPR(4); + ARG_FPR(3); + ARG_FPR(2); + ARG_FPR(1); + ARG_FPR(0); + case 0:; +#undef ARG_FPR + } + + // Load GPR registers from gpregs[] + register PRUint64 a0 asm("rdi"); + register PRUint64 a1 asm("rsi"); + register PRUint64 a2 asm("rdx"); + register PRUint64 a3 asm("rcx"); + register PRUint64 a4 asm("r8"); + register PRUint64 a5 asm("r9"); + + switch (nr_gpr) { +#define ARG_GPR(N) \ + case N+1: a##N = gpregs[N]; + ARG_GPR(5); + ARG_GPR(4); + ARG_GPR(3); + ARG_GPR(2); + ARG_GPR(1); + case 1: a0 = (PRUint64) that; + case 0:; +#undef ARG_GPR + } + + // Ensure that assignments to SSE registers won't be optimized away + asm("" :: + "x" (d0), "x" (d1), "x" (d2), "x" (d3), + "x" (d4), "x" (d5), "x" (d6), "x" (d7)); + + // Get pointer to method + PRUint64 methodAddress = *((PRUint64 *)that); + methodAddress += 8 * methodIndex; + methodAddress = *((PRUint64 *)methodAddress); + + typedef PRUint32 (*Method)(PRUint64, PRUint64, PRUint64, PRUint64, PRUint64, PRUint64); + PRUint32 result = ((Method)methodAddress)(a0, a1, a2, a3, a4, a5); + return result; + +#pragma clang diagnostic pop +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_amd64_vbox.asm b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_amd64_vbox.asm new file mode 100644 index 00000000..c0746855 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_amd64_vbox.asm @@ -0,0 +1,403 @@ +; $Id: xptcinvoke_amd64_vbox.asm $ +;; @file +; XPCOM - Implementation XPTC_InvokeByIndex in assembly. +; +; This solves the problem of Clang and gcc (sometimes) not playing along with +; the alloca() based trick to pass stack parameters. We first had trouble +; when enabling asan with gcc 8.2, then Clang 11 on mac had similar issues +; (at least for profile builds). +; + +; +; Copyright (C) 2020-2022 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; SPDX-License-Identifier: GPL-3.0-only +; + + +;********************************************************************************************************************************* +;* Internal Functions * +;********************************************************************************************************************************* +%include "iprt/asmdefs.mac" + + +;********************************************************************************************************************************* +;* Structures and Typedefs * +;********************************************************************************************************************************* +struc nsXPTCVariant + .val resq 1 + .ptr resq 1 + .type resb 1 + .flags resb 1 + alignb 8 +endstruc + + +;********************************************************************************************************************************* +;* Defined Constants And Macros * +;********************************************************************************************************************************* +;; @name Selected nsXPTCVariant::flags values. +;; @{ +%define PTR_IS_DATA 1 +;; @} + +;; @name Selected nsXPTType (nsXPTCVariant::type) values. +;; @{ +%define T_FLOAT 8 +%define T_DOUBLE 9 +;; @} + +;; Error code we use if there are too many parameters. +%define DISP_E_BADPARAMCOUNT 0x8002000e + +;; Effect name mangling. +%ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP + %define XPTC_InvokeByIndex VBoxNsxpXPTC_InvokeByIndex +%endif + + +BEGINCODE + +;; +; +; @cproto nsresult XPTC_InvokeByIndex(nsISupports *pThat, PRUint32 idxMethod, PRUint32 cParams, nsXPTCVariant *paParams) +; +; @param pThat Pointer to the object we're invoking a method on. register:rdi +; @param idxMethod The VTable method index. register:esi +; @param cParams Number of parameters in addition to pThat. register:edx +; @param paParams Array of parameter values and info. register:rcx +; +BEGINPROC_EXPORTED XPTC_InvokeByIndex + push rbp + mov rbp, rsp + push rbx + push r12 + + ; + ; Move essential input parameters into non-parameter registers. + ; + mov rbx, rcx ; rbx = first / current parameter + mov r12d, edx ; r12 = parameter count / left + + ; Look up the method address in the vtable and store it in r11 (freeing up rsi). + mov r11, [rdi] ; r11 = vtable + mov esi, esi ; zero extend vtable index. + mov r11, [r11 + rsi * 8] ; r11 = method to call. + +%define WITH_OPTIMIZATION +%ifdef WITH_OPTIMIZATION + ; + ; If there are 5 or fewer parameters and they are all suitable for GREGs, + ; we can try optimize the processing here. + ; + ; Switch on count, using fall-thought-to-smaller-value logic, default + ; case goes to generic (slow) code path. + ; + dec edx ; we can still use edx for the parameter count here as a throwaway. + jz .fast_1 + dec edx + jz .fast_2 + dec edx + jz .fast_3 + dec edx + jz .fast_4 + dec edx + jnz .slow_or_zero +%macro fast_case 4 +%1: + mov eax, [rbx + nsXPTCVariant_size * %3 + nsXPTCVariant.type] ; ASSUMES 'type' and 'flags' are adjacent byte fields. + test ah, PTR_IS_DATA + mov %4, [rbx + nsXPTCVariant_size * %3 + nsXPTCVariant.ptr] + jnz %2 + sub al, T_FLOAT + sub al, 2 + jl .fast_bailout + mov %4, [rbx + nsXPTCVariant_size * %3 + nsXPTCVariant.val] +%endmacro + fast_case .fast_5, .fast_4, 4, r9 + fast_case .fast_4, .fast_3, 3, r8 + fast_case .fast_3, .fast_2, 2, rcx + fast_case .fast_2, .fast_1, 1, rdx + fast_case .fast_1, .fast_0, 0, rsi +.fast_0: + xor eax, eax + call r11 ; note! stack is aligned here. + +.fast_return: + lea rsp, [rbp - 8*2] + pop r12 + pop rbx + leave + ret + +.slow_or_zero: + cmp r12d, 0 + je .fast_0 + %if 0 + jmp .slow +.fast_bailout: + int3 + %else +.fast_bailout: + %endif +.slow: +%endif + ; One more push. + push r13 + + ; + ; Check that there aren't unreasonably many parameters + ; (we could do ~255, but 64 is more reasonable number). + ; + cmp r12d, 64 + je .too_many_parameters + + ; + ; For simplicity reserve stack space for all parameters and point r10 at it. + ; + lea edx, [r12d * 8] + sub rsp, rdx + and rsp, byte 0ffffffffffffffe0h ; 32 byte aligned stack. + mov r10, rsp ; r10 = next stack parameter. + + ; + ; Set up parameter pointer and register distribution counts. + ; + mov eax, 1 ; al = greg count, ah = fpreg count. + + ; + ; Anything to do here? + ; +%ifndef WITH_OPTIMIZATION + test r12d,r12d + jz .make_call +%endif + jmp .param_loop + + ; + ; The loop. + ; + ALIGNCODE(64) +.param_loop_advance: + add rbx, nsXPTCVariant_size +.param_loop: + ; First test for pointers using 'flags' then work 'type' for the rest. + test byte [rbx + nsXPTCVariant.flags], PTR_IS_DATA + jnz .is_ptr + cmp byte [rbx + nsXPTCVariant.type], T_FLOAT + jge .maybe_in_fpreg + + ; + ; nsXPTCVariant.val belongs in a GREG or on the stack. + ; Note! Hope we can get away with not zero extending the value here. + ; +.in_greg: + inc al + cmp al, 1+1 + je .in_greg_rsi + cmp al, 2+1 + je .in_greg_rdx + cmp al, 3+1 + je .in_greg_rcx + cmp al, 4+1 + je .in_greg_r8 + cmp al, 5+1 + ja .on_stack +.in_greg_r9: + mov r9, [rbx + nsXPTCVariant.val] + jmp .next +.in_greg_r8: + mov r8, [rbx + nsXPTCVariant.val] + jmp .next +.in_greg_rcx: + mov rcx, [rbx + nsXPTCVariant.val] + jmp .next +.in_greg_rdx: + mov rdx, [rbx + nsXPTCVariant.val] + jmp .next +.in_greg_rsi: + mov rsi, [rbx + nsXPTCVariant.val] + jmp .next + + ; + ; Pointers are loaded from the 'ptr' rather than the 'val' member. + ; + ALIGNCODE(64) +.is_ptr: + inc al + cmp al, 1+1 + je .ptr_in_greg_rsi + cmp al, 2+1 + je .ptr_in_greg_rdx + cmp al, 3+1 + je .ptr_in_greg_rcx + cmp al, 4+1 + je .ptr_in_greg_r8 + cmp al, 5+1 + je .ptr_in_greg_r9 + mov r13, [rbx + nsXPTCVariant.ptr] + jmp .r13_on_stack + +.ptr_in_greg_r9: + mov r9, [rbx + nsXPTCVariant.ptr] + jmp .next +.ptr_in_greg_r8: + mov r8, [rbx + nsXPTCVariant.ptr] + jmp .next +.ptr_in_greg_rcx: + mov rcx, [rbx + nsXPTCVariant.ptr] + jmp .next +.ptr_in_greg_rdx: + mov rdx, [rbx + nsXPTCVariant.ptr] + jmp .next +.ptr_in_greg_rsi: + mov rsi, [rbx + nsXPTCVariant.ptr] + jmp .next + + ; + ; Maybe we've got a float or double type here... + ; +.maybe_in_fpreg: + je .float_in_fpreg + cmp byte [rbx + nsXPTCVariant.type], T_DOUBLE + jne .in_greg + +.double_in_fpreg: + cmp ah, 8 ; Ensure max AL value of 8 when making call. + jge .on_stack + inc ah + cmp ah, 0+1 + je .double_in_xmm0 + cmp ah, 1+1 + je .double_in_xmm1 + cmp ah, 2+1 + je .double_in_xmm2 + cmp ah, 3+1 + je .double_in_xmm3 + cmp ah, 4+1 + je .double_in_xmm4 + cmp ah, 5+1 + je .double_in_xmm5 + cmp ah, 6+1 + je .double_in_xmm6 +.double_in_xmm7: + movsd xmm7, [rbx + nsXPTCVariant.val] + jmp .next +.double_in_xmm6: + movsd xmm6, [rbx + nsXPTCVariant.val] + jmp .next +.double_in_xmm5: + movsd xmm5, [rbx + nsXPTCVariant.val] + jmp .next +.double_in_xmm4: + movsd xmm4, [rbx + nsXPTCVariant.val] + jmp .next +.double_in_xmm3: + movsd xmm3, [rbx + nsXPTCVariant.val] + jmp .next +.double_in_xmm2: + movsd xmm2, [rbx + nsXPTCVariant.val] + jmp .next +.double_in_xmm1: + movsd xmm1, [rbx + nsXPTCVariant.val] + jmp .next +.double_in_xmm0: + movsd xmm0, [rbx + nsXPTCVariant.val] + jmp .next + +.float_in_fpreg: + cmp ah, 8 ; Ensure max AL value of 8 when making call. + jge .on_stack + inc ah + cmp ah, 0+1 + je .float_in_xmm0 + cmp ah, 1+1 + je .float_in_xmm1 + cmp ah, 2+1 + je .float_in_xmm2 + cmp ah, 3+1 + je .float_in_xmm3 + cmp ah, 4+1 + je .float_in_xmm4 + cmp ah, 5+1 + je .float_in_xmm5 + cmp ah, 6+1 + je .float_in_xmm6 +.float_in_xmm7: + movss xmm7, [rbx + nsXPTCVariant.val] + jmp .next +.float_in_xmm6: + movss xmm6, [rbx + nsXPTCVariant.val] + jmp .next +.float_in_xmm5: + movss xmm5, [rbx + nsXPTCVariant.val] + jmp .next +.float_in_xmm4: + movss xmm4, [rbx + nsXPTCVariant.val] + jmp .next +.float_in_xmm3: + movss xmm3, [rbx + nsXPTCVariant.val] + jmp .next +.float_in_xmm2: + movss xmm2, [rbx + nsXPTCVariant.val] + jmp .next +.float_in_xmm1: + movss xmm1, [rbx + nsXPTCVariant.val] + jmp .next +.float_in_xmm0: + movss xmm0, [rbx + nsXPTCVariant.val] + jmp .next + + ; + ; Put the value onto the stack via r13. + ; + ALIGNCODE(64) +.on_stack: + mov r13, [rbx + nsXPTCVariant.val] +.r13_on_stack: + mov [r10], r13 + lea r10, [r10 + 8] + + ; + ; Update parameter pointer and count and maybe loop again. + ; +.next: + dec r12d + jnz .param_loop_advance + + ; + ; Call the method and return. + ; +.make_call: + movzx eax, ah ; AL = number of parameters in XMM registers (variadict only, but easy to do). +.make_just_call: + call r11 + +.return: + lea rsp, [rbp - 8*3] + pop r13 + pop r12 + pop rbx + leave + ret + +.too_many_parameters: + mov eax, DISP_E_BADPARAMCOUNT + jmp .return +ENDPROC XPTC_InvokeByIndex diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp new file mode 100644 index 00000000..1b2c5c67 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp @@ -0,0 +1,220 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +#if !defined(LINUX) || !defined(__arm__) +#error "This code is for Linux ARM only. Check that it works on your system, too.\nBeware that this code is highly compiler dependent." +#endif + +// Remember that these 'words' are 32bit DWORDS + +static PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 result = 0; + for(PRUint32 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; + } + } + return result; +} + +static void +invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s) +{ + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : *((PRInt8*) d) = s->val.i8; break; + case nsXPTType::T_I16 : *((PRInt16*) d) = s->val.i16; break; + case nsXPTType::T_I32 : *((PRInt32*) d) = s->val.i32; break; + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U8 : *((PRUint8*) d) = s->val.u8; break; + case nsXPTType::T_U16 : *((PRUint16*)d) = s->val.u16; break; + case nsXPTType::T_U32 : *((PRUint32*)d) = s->val.u32; break; + case nsXPTType::T_U64 : *((PRUint64*)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 : *((PRBool*) 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" { + struct my_params_struct { + nsISupports* that; + PRUint32 Index; + PRUint32 Count; + nsXPTCVariant* params; + PRUint32 fn_count; + PRUint32 fn_copy; + }; +}; + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + PRUint32 result; + struct my_params_struct my_params; + my_params.that = that; + my_params.Index = methodIndex; + my_params.Count = paramCount; + my_params.params = params; + my_params.fn_copy = (PRUint32) &invoke_copy_to_stack; + my_params.fn_count = (PRUint32) &invoke_count_words; + +/* This is to call a given method of class that. + * The parameters are in params, the number is in paramCount. + * The routine will issue calls to count the number of words + * required for argument passing and to copy the arguments to + * the stack. + * Since APCS passes the first 3 params in r1-r3, we need to + * load the first three words from the stack and correct the stack + * pointer (sp) in the appropriate way. This means: + * + * 1.) more than 3 arguments: load r1-r3, correct sp and remember No. + * of bytes left on the stack in r4 + * + * 2.) <= 2 args: load r1-r3 (we won't be causing a stack overflow I hope), + * restore sp as if nothing had happened and set the marker r4 to zero. + * + * Afterwards sp will be restored using the value in r4 (which is not a temporary register + * and will be preserved by the function/method called according to APCS [ARM Procedure + * Calling Standard]). + * + * !!! IMPORTANT !!! + * This routine makes assumptions about the vtable layout of the c++ compiler. It's implemented + * for arm-linux GNU g++ >= 2.8.1 (including egcs and gcc-2.95.[1-3])! + * + */ + + __asm__ __volatile__( + "ldr r1, [%1, #12] \n\t" /* prepare to call invoke_count_words */ + "ldr ip, [%1, #16] \n\t" /* r0=paramCount, r1=params */ + "ldr r0, [%1, #8] \n\t" + "mov lr, pc \n\t" /* call it... */ + "mov pc, ip \n\t" + "mov r4, r0, lsl #2 \n\t" /* This is the amount of bytes needed. */ + "sub sp, sp, r4 \n\t" /* use stack space for the args... */ + "mov r0, sp \n\t" /* prepare a pointer an the stack */ + "ldr r1, [%1, #8] \n\t" /* =paramCount */ + "ldr r2, [%1, #12] \n\t" /* =params */ + "ldr ip, [%1, #20] \n\t" /* =invoke_copy_to_stack */ + "mov lr, pc \n\t" /* copy args to the stack like the */ + "mov pc, ip \n\t" /* compiler would. */ + "ldr r0, [%1] \n\t" /* =that */ + "ldr r1, [r0, #0] \n\t" /* get that->vtable offset */ + "ldr r2, [%1, #4] \n\t" + "mov r2, r2, lsl #2 \n\t" /* a vtable_entry(x)=8 + (4 bytes * x) */ +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + "ldr ip, [r1, r2] \n\t" /* get method adress from vtable */ +#else /* non G++ V3 ABI */ + "add r2, r2, #8 \n\t" /* with this compilers */ + "ldr ip, [r1, r2] \n\t" /* get method adress from vtable */ +#endif + "cmp r4, #12 \n\t" /* more than 3 arguments??? */ + "ldmgtia sp!, {r1, r2, r3}\n\t" /* yes: load arguments for r1-r3 */ + "subgt r4, r4, #12 \n\t" /* and correct the stack pointer */ + "ldmleia sp, {r1, r2, r3}\n\t" /* no: load r1-r3 from stack */ + "addle sp, sp, r4 \n\t" /* and restore stack pointer */ + "movle r4, #0 \n\t" /* a mark for restoring sp */ + "ldr r0, [%1, #0] \n\t" /* get (self) */ + "mov lr, pc \n\t" /* call mathod */ + "mov pc, ip \n\t" + "add sp, sp, r4 \n\t" /* restore stack pointer */ + "mov %0, r0 \n\t" /* the result... */ + : "=r" (result) + : "r" (&my_params) + : "r0", "r1", "r2", "r3", "r4", "ip", "lr", "sp" + ); + + return result; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm64_vbox.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm64_vbox.cpp new file mode 100644 index 00000000..6611f667 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm64_vbox.cpp @@ -0,0 +1,296 @@ +/* $Id: xptcinvoke_arm64_vbox.cpp $ */ +/** @file + * XPCOM - Implementation XPTC_InvokeByIndex for arm64. + */ + +/* + * Copyright (C) 2021-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "xptcprivate.h" +#include <iprt/cdefs.h> +#include <iprt/alloca.h> +#include <iprt/assert.h> + + +/********************************************************************************************************************************* +* Defined Constants And Macros * +*********************************************************************************************************************************/ +#define NUM_ARGS_IN_GPRS 8 /**< Number of arguments passed in general purpose registers (starting with x0). */ +#define NUM_ARGS_IN_FPRS 8 /**< Number of arguments passed in floating point registers (starting with d0). */ + +#define MY_MAX_ARGS 64 /**< Limit ourselves to 64 arguments. */ + + + +AssertCompileMemberOffset(nsXPTCVariant, val, 0); + +extern "C" __attribute__((naked)) nsresult +arm64AsmInvoker(uintptr_t pfnMethod /*x0*/, uint32_t cParams /*w1*/, nsXPTCVariant *paParams /*x2*/, uint64_t cbStack /*x3*/, + uint8_t *acbStackArgs /*x4*/, uint64_t *pauGprArgs /*x5*/, uint64_t *pauFprArgs /*x6*/, uint32_t cFprArgs /*x7*/) +{ + __asm__ __volatile__( + /* Prologue - create the frame. */ "\ + sub sp, sp, 16 \n\ + stp x29, x30, [sp] \n\ + mov x29, sp \n\ + .cfi_def_cfa x29, 16 \n\ + .cfi_rel_offset x30, -8 \n\ + .cfi_rel_offset x29, -16 \n\ +\n\ +" /* Move pfnMethod to x16 and pauGprArgs to x7 free up x0 and x5: */ "\ + mov x16, x0 \n\ + mov x17, x5 \n\ +\n\ +" /* Load FPU registers first so we free up x6 & x7 early: */ "\ + cmp w7, #0 \n\ + b.eq Lno_fprs\n\ + ldp d0, d1, [x6] \n\ + ldp d2, d3, [x6, #16] \n\ + ldp d4, d5, [x6, #32] \n\ + ldp d6, d7, [x6, #48] \n\ +Lno_fprs:\n\ +\n\ +" /* Do argument passing by stack (if any). We align the stack to 16 bytes. */ "\ + cmp x3, #0 \n\ + beq Lno_stack_args \n\ + sub x3, sp, x3 \n\ + bic x3, x3, #15 \n\ + mov sp, x3 \n\ +Lnext_parameter: \n\ + ldrb w7, [x4] \n\ + cmp w7, #0 \n\ + beq Ladvance\n\ +\n\ + cmp w7, #4 \n\ + bgt Lstore_64bits\n\ + cmp w7, #1 \n\ + beq Lstore_8bits\n\ + cmp w7, #2 \n\ + beq Lstore_16bits\n\ +\n\ +Lstore_32bits:\n\ + ldr w0, [x2] \n\ + add x3, x3, #3 \n\ + bic x3, x3, #3 \n\ + str w0, [x3] \n" +#ifdef RT_OS_DARWIN /* macOS compacts stack usage. */ +" add x3, x3, #4 \n" +#endif +" b Ladvance \n\ +\n\ +Lstore_8bits:\n\ + ldrb w0, [x2] \n\ + strb w0, [x3] \n" +#ifdef RT_OS_DARWIN /* macOS compacts stack usage. */ +" add x3, x3, #1 \n" +#endif +" b Ladvance \n\ +\n\ +Lstore_16bits:\n\ + ldrh w0, [x2] \n\ + add x3, x3, #1 \n\ + bic x3, x3, #1 \n\ + strh w0, [x3] \n" +#ifdef RT_OS_DARWIN /* macOS compacts stack usage. */ +" add x3, x3, #2 \n" +#endif +" b Ladvance \n\ +\n\ +Lstore_64bits_ptr:\n\ + ldr x0, [x2, %[offPtrInXPTCVariant]] \n\ + b Lstore_64bits_common \n\ +Lstore_64bits:\n\ + tst w7, #0x80 \n\ + bne Lstore_64bits_ptr \n\ + ldr x0, [x2] \n\ +Lstore_64bits_common:\n\ + add x3, x3, #7 \n\ + bic x3, x3, #7 \n\ + str x0, [x3] \n" +#ifdef RT_OS_DARWIN /* macOS compacts stack usage. */ +" add x3, x3, #8 \n" +#endif +"\n\ +Ladvance:\n" +#ifndef RT_OS_DARWIN /* macOS compacts stack usage. */ +" add x3, x3, #8 \n" +#endif +" add x4, x4, #1 \n\ + add x2, x2, %[cbXPTCVariant] \n\ + sub w1, w1, #1 \n\ + cmp w1, #0 \n\ + bne Lnext_parameter \n\ +\n\ +" /* reserve stack space for the integer and floating point registers and save them: */ "\ +Lno_stack_args: \n\ +\n\ +" /* Load general purpose argument registers: */ "\ + ldp x0, x1, [x17] \n\ + ldp x2, x3, [x17, #16] \n\ + ldp x4, x5, [x17, #32] \n\ + ldp x6, x7, [x17, #48] \n\ +\n\ +" /* Make the call: */ "\ + blr x16 \n\ +\n\ +" /* Epilogue (clang does not emit the .cfi's here, so drop them too?): */ "\ + mov sp, x29 \n\ + ldp x29, x30, [sp] \n\ + add sp, sp, #16 \n\ + .cfi_def_cfa sp, 0 \n\ + .cfi_restore x29 \n\ + .cfi_restore x30 \n\ + ret \n\ +" : + : [cbXPTCVariant] "i" (sizeof(nsXPTCVariant)) + , [offPtrInXPTCVariant] "i" (offsetof(nsXPTCVariant, ptr)) + :); +} + + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports *pThis, PRUint32 idxMethod, PRUint32 cParams, nsXPTCVariant *paParams) +{ + AssertMsgReturn(cParams <= MY_MAX_ARGS, ("cParams=%#x idxMethod=%#x\n", cParams, idxMethod), NS_ERROR_UNEXPECTED); + + /* + * Prepare + */ + uint64_t auGprArgs[NUM_ARGS_IN_GPRS] = {0}; + uint64_t auFprArgs[NUM_ARGS_IN_GPRS] = {0}; + uint8_t acbStackArgs[MY_MAX_ARGS]; /* The number of value bytes to copy onto the stack. Zero if in register. */ + uint32_t cbStackArgs = 0; + uint32_t cFprArgs = 0; + uint32_t cGprArgs = 0; + + /* First argument is always 'pThis'. The 'pThis' argument is not accounted + for in cParams or acbStackArgs. */ + auGprArgs[cGprArgs++] = (uintptr_t)pThis; + + /* Do the other arguments. */ + for (PRUint32 i = 0; i < cParams; i++) + { + if (paParams[i].IsPtrData()) + { + if (cGprArgs < NUM_ARGS_IN_GPRS) + { + auGprArgs[cGprArgs++] = (uintptr_t)paParams[i].ptr; + acbStackArgs[i] = 0; + } + else + { + acbStackArgs[i] = sizeof(paParams[i].ptr) | UINT8_C(0x80); +#ifdef RT_OS_DARWIN /* macOS compacts stack usage. */ + cbStackArgs = RT_ALIGN_32(cbStackArgs, sizeof(paParams[i].ptr)) + sizeof(paParams[i].ptr); +#else + cbStackArgs += sizeof(uint64_t); +#endif + } + } + else + { + if ( paParams[i].type != nsXPTType::T_FLOAT + && paParams[i].type != nsXPTType::T_DOUBLE) + { + if (cGprArgs < NUM_ARGS_IN_GPRS) + { + switch (paParams[i].type) + { + case nsXPTType::T_I8: auGprArgs[cGprArgs++] = paParams[i].val.i8; break; + case nsXPTType::T_I16: auGprArgs[cGprArgs++] = paParams[i].val.i16; break; + case nsXPTType::T_I32: auGprArgs[cGprArgs++] = paParams[i].val.i32; break; + case nsXPTType::T_I64: auGprArgs[cGprArgs++] = paParams[i].val.i64; break; + case nsXPTType::T_U8: auGprArgs[cGprArgs++] = paParams[i].val.u8; break; + case nsXPTType::T_U16: auGprArgs[cGprArgs++] = paParams[i].val.u16; break; + case nsXPTType::T_U32: auGprArgs[cGprArgs++] = paParams[i].val.u32; break; + default: + case nsXPTType::T_U64: auGprArgs[cGprArgs++] = paParams[i].val.u64; break; + case nsXPTType::T_BOOL: auGprArgs[cGprArgs++] = paParams[i].val.b; break; + case nsXPTType::T_CHAR: auGprArgs[cGprArgs++] = paParams[i].val.c; break; + case nsXPTType::T_WCHAR: auGprArgs[cGprArgs++] = paParams[i].val.wc; break; + } + acbStackArgs[i] = 0; + } + else + { + uint8_t cbStack; + switch (paParams[i].type) + { + case nsXPTType::T_I8: cbStack = sizeof(paParams[i].val.i8); break; + case nsXPTType::T_I16: cbStack = sizeof(paParams[i].val.i16); break; + case nsXPTType::T_I32: cbStack = sizeof(paParams[i].val.i32); break; + case nsXPTType::T_I64: cbStack = sizeof(paParams[i].val.i64); break; + case nsXPTType::T_U8: cbStack = sizeof(paParams[i].val.u8); break; + case nsXPTType::T_U16: cbStack = sizeof(paParams[i].val.u16); break; + case nsXPTType::T_U32: cbStack = sizeof(paParams[i].val.u32); break; + default: + case nsXPTType::T_U64: cbStack = sizeof(paParams[i].val.u64); break; + case nsXPTType::T_BOOL: cbStack = sizeof(paParams[i].val.b); break; + case nsXPTType::T_CHAR: cbStack = sizeof(paParams[i].val.c); break; + case nsXPTType::T_WCHAR: cbStack = sizeof(paParams[i].val.wc); break; + } + acbStackArgs[i] = cbStack; +#ifdef RT_OS_DARWIN /* macOS compacts stack usage. */ + cbStackArgs = RT_ALIGN_32(cbStackArgs, cbStack) + cbStack; +#else + cbStackArgs += sizeof(uint64_t); +#endif + } + } + else if (cFprArgs < NUM_ARGS_IN_FPRS) + { + AssertCompile(sizeof(paParams[i].val.f) == 4); + AssertCompile(sizeof(paParams[i].val.d) == 8); + if (paParams[i].type == nsXPTType::T_FLOAT) + auFprArgs[cFprArgs++] = paParams[i].val.u32; + else + auFprArgs[cFprArgs++] = paParams[i].val.u64; + acbStackArgs[i] = 0; + } + else + { + uint8_t cbStack; + if (paParams[i].type == nsXPTType::T_FLOAT) + cbStack = sizeof(paParams[i].val.f); + else + cbStack = sizeof(paParams[i].val.d); + acbStackArgs[i] = cbStack; +#ifdef RT_OS_DARWIN /* macOS compacts stack usage. */ + cbStackArgs = RT_ALIGN_32(cbStackArgs, cbStack) + cbStack; +#else + cbStackArgs += sizeof(uint64_t); +#endif + } + } + } + + /* + * Pass it on to a naked wrapper function that does the nitty gritty work. + */ + uintptr_t *pauVtable = *(uintptr_t **)pThis; + return arm64AsmInvoker(pauVtable[idxMethod], cParams, paParams, cbStackArgs, acbStackArgs, auGprArgs, auFprArgs, cFprArgs); +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm_netbsd.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm_netbsd.cpp new file mode 100644 index 00000000..0213bd76 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm_netbsd.cpp @@ -0,0 +1,213 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +// Remember that these 'words' are 32bit DWORDS + +static PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 result = 0; + for(PRUint32 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; + } + } + return result; +} + +static void +invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s) +{ + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : *((PRInt8*) d) = s->val.i8; break; + case nsXPTType::T_I16 : *((PRInt16*) d) = s->val.i16; break; + case nsXPTType::T_I32 : *((PRInt32*) d) = s->val.i32; break; + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U8 : *((PRUint8*) d) = s->val.u8; break; + case nsXPTType::T_U16 : *((PRUint16*)d) = s->val.u16; break; + case nsXPTType::T_U32 : *((PRUint32*)d) = s->val.u32; break; + case nsXPTType::T_U64 : *((PRUint64*)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 : *((PRBool*) 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" +struct my_params_struct { + nsISupports* that; + PRUint32 Index; + PRUint32 Count; + nsXPTCVariant* params; + PRUint32 fn_count; + PRUint32 fn_copy; +}; + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + PRUint32 result; + struct my_params_struct my_params; + my_params.that = that; + my_params.Index = methodIndex; + my_params.Count = paramCount; + my_params.params = params; + my_params.fn_copy = (PRUint32) &invoke_copy_to_stack; + my_params.fn_count = (PRUint32) &invoke_count_words; + +/* This is to call a given method of class that. + * The parameters are in params, the number is in paramCount. + * The routine will issue calls to count the number of words + * required for argument passing and to copy the arguments to + * the stack. + * Since APCS passes the first 3 params in r1-r3, we need to + * load the first three words from the stack and correct the stack + * pointer (sp) in the appropriate way. This means: + * + * 1.) more than 3 arguments: load r1-r3, correct sp and remember No. + * of bytes left on the stack in r4 + * + * 2.) <= 2 args: load r1-r3 (we won't be causing a stack overflow I hope), + * restore sp as if nothing had happened and set the marker r4 to zero. + * + * Afterwards sp will be restored using the value in r4 (which is not a temporary register + * and will be preserved by the function/method called according to APCS [ARM Procedure + * Calling Standard]). + * + * !!! IMPORTANT !!! + * This routine makes assumptions about the vtable layout of the c++ compiler. It's implemented + * for arm-linux GNU g++ >= 2.8.1 (including egcs and gcc-2.95.[1-3])! + * + */ + + __asm__ __volatile__( + "ldr r1, [%1, #12] \n\t" /* prepare to call invoke_count_words */ + "ldr ip, [%1, #16] \n\t" /* r0=paramCount, r1=params */ + "ldr r0, [%1, #8] \n\t" + "mov lr, pc \n\t" /* call it... */ + "mov pc, ip \n\t" + "mov r4, r0, lsl #2 \n\t" /* This is the amount of bytes needed. */ + "sub sp, sp, r4 \n\t" /* use stack space for the args... */ + "mov r0, sp \n\t" /* prepare a pointer an the stack */ + "ldr r1, [%1, #8] \n\t" /* =paramCount */ + "ldr r2, [%1, #12] \n\t" /* =params */ + "ldr ip, [%1, #20] \n\t" /* =invoke_copy_to_stack */ + "mov lr, pc \n\t" /* copy args to the stack like the */ + "mov pc, ip \n\t" /* compiler would. */ + "ldr r0, [%1] \n\t" /* =that */ + "ldr r1, [r0, #0] \n\t" /* get that->vtable offset */ + "ldr r2, [%1, #4] \n\t" + "add r2, r1, r2, lsl #3\n\t" /* a vtable_entry(x)=8 + (8 bytes * x) */ + "add r2, r2, #8 \n\t" /* with this compilers */ + "ldr r3, [r2] \n\t" /* get virtual offset from vtable */ + "mov r3, r3, lsl #16 \n\t" + "add r0, r0, r3, asr #16\n\t" + "ldr ip, [r2, #4] \n\t" /* get method address from vtable */ + "cmp r4, #12 \n\t" /* more than 3 arguments??? */ + "ldmgtia sp!, {r1, r2, r3}\n\t" /* yes: load arguments for r1-r3 */ + "subgt r4, r4, #12 \n\t" /* and correct the stack pointer */ + "ldmleia sp, {r1, r2, r3}\n\t" /* no: load r1-r3 from stack */ + "addle sp, sp, r4 \n\t" /* and restore stack pointer */ + "movle r4, #0 \n\t" /* a mark for restoring sp */ + "mov lr, pc \n\t" /* call mathod */ + "mov pc, ip \n\t" + "add sp, sp, r4 \n\t" /* restore stack pointer */ + "mov %0, r0 \n\t" /* the result... */ + : "=r" (result) + : "r" (&my_params) + : "r0", "r1", "r2", "r3", "r4", "ip", "lr" + ); + + return result; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf32.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf32.s new file mode 100644 index 00000000..c846b1f4 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf32.s @@ -0,0 +1,145 @@ + +// Select C numeric constant + .radix C +// for 64 bit mode, use .psr abi64 + .psr abi32 +// big endian + .psr msb +// Section has executable code + .section .text, "ax","progbits" +// procedure named 'XPTC_InvokeByIndex' + .proc XPTC_InvokeByIndex +// manual bundling + .explicit + +// extern "C" PRUint32 +// invoke_copy_to_stack(uint64_t* d, +// const PRUint32 paramCount, nsXPTCVariant* s) + .global invoke_copy_to_stack +// .exclass invoke_copy_to_stack, @fullyvisible + .type invoke_copy_to_stack,@function + +// .exclass XPTC_InvokeByIndex, @fullyvisible + .type XPTC_InvokeByIndex,@function + +// XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +// PRUint32 paramCount, nsXPTCVariant* params); +XPTC_InvokeByIndex:: + .prologue + .save ar.pfs, r37 +// allocate 4 input args, 6 local args, and 8 output args + alloc r37 = ar.pfs, 4, 6, 8, 0 // M + nop.i 0 ;; // I + +// unwind table already knows gp, no need to specify anything + add r39 = 0, gp // A + .save rp, r36 + mov r36 = rp // I + .vframe r38 + add r38 = 0, sp ;; // A + +// We first calculate the amount of extra memory stack space required +// for the arguments, and register storage. +// We then call invoke_copy_to_stack() to write the argument contents +// to the specified memory regions. +// We then copy the integer arguments to integer registers, and floating +// arguments to float registers. +// Lastly we load the virtual table jump pointer, and call the target +// subroutine. + +// in0 : that +// in1 : methodIndex +// in2 : paramCount +// in3 : params + +// stack frame size is 16 + (8 * even(paramCount)) + 64 + 64 +// 16 byte frame header +// 8 * even(paramCount) memory argument area +// 64 bytes integer register area +// 64 bytes float register area +// This scheme makes sure stack fram size is a multiple of 16 + + .body + add r10 = 8, r0 // A +// r41 points to float register area + add r41 = -64, sp // A +// r40 points to int register area + add r40 = -128, sp ;; // A + + add out1 = 0, r40 // A + add out2 = 0, r41 // A + tbit.z p14,p15 = in2,0 ;; // I + +// compute 8 * even(paramCount) +(p14) shladd r11 = in2, 3, r0 ;; // A +(p15) shladd r11 = in2, 3, r10 ;; // A + sub out0 = r40, r11 ;; // A + +// advance the stack frame + add sp = -16, out0 // A + add out3 = 0, in2 // A + add out4 = 0, in3 // A + +// branch to invoke_copy_to_stack + br.call.sptk.few rp = invoke_copy_to_stack ;; // B + +// restore gp + add gp = 0, r39 // A + add out0 = 0, in0 // A + +// load the integer and float registers + ld8 out1 = [r40], 8 // M + ldfd f8 = [r41], 8 ;; // M + + ld8 out2 = [r40], 8 // M + ldfd f9 = [r41], 8 ;; // M + + ld8 out3 = [r40], 8 // M + ldfd f10 = [r41], 8 ;; // M + + ld8 out4 = [r40], 8 // M + ldfd f11 = [r41], 8 ;; // M + + ld8 out5 = [r40], 8 // M + ldfd f12 = [r41], 8 ;; // M +// 16 * methodIndex + shladd r11 = in1, 4, r0 // A + + ld8 out6 = [r40], 8 // M + ldfd f13 = [r41], 8 ;; // M + + ld8 out7 = [r40], 8 // M + ldfd f14 = [r41], 8 // M + addp4 r8 = 0, in0 ;; // A + +// look up virtual base table and dispatch to target subroutine +// This section assumes 32 bit pointer mode, and virtual base table +// layout from the ABI http://www.codesourcery.com/cxx-abi/abi.html + +// load base table + ld4 r8 = [r8] ;; // M + addp4 r8 = r11, r8 ;; // A + + // first entry is jump pointer, second entry is gp + addp4 r9 = 8, r8 ;; // A +// load jump pointer + ld8 r8 = [r8] + +// load gp + ld8 gp = [r9] ;; // M + mov b6 = r8 ;; // I + +// branch to target virtual function + br.call.sptk.few rp = b6 ;; // B + +// epilog + mov ar.pfs = r37 // I + mov rp = r36 ;; // I + + add sp = 0, r38 // A + add gp = 0, r39 // A + br.ret.sptk.few rp ;; // B + + .endp + + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf64.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf64.s new file mode 100644 index 00000000..5e1b1a23 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf64.s @@ -0,0 +1,145 @@ + +// Select C numeric constant + .radix C +// for 64 bit mode, use .psr abi64 + .psr abi64 +// little endian + .psr lsb +// Section has executable code + .section .text, "ax","progbits" +// procedure named 'XPTC_InvokeByIndex' + .proc XPTC_InvokeByIndex +// manual bundling + .explicit + +// extern "C" PRUint32 +// invoke_copy_to_stack(uint64_t* d, +// const PRUint32 paramCount, nsXPTCVariant* s) + .global invoke_copy_to_stack +// .exclass invoke_copy_to_stack, @fullyvisible + .type invoke_copy_to_stack,@function + +// .exclass XPTC_InvokeByIndex, @fullyvisible + .type XPTC_InvokeByIndex,@function + +// XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +// PRUint32 paramCount, nsXPTCVariant* params); +XPTC_InvokeByIndex:: + .prologue + .save ar.pfs, r37 +// allocate 4 input args, 6 local args, and 8 output args + alloc r37 = ar.pfs, 4, 6, 8, 0 // M + nop.i 0 ;; // I + +// unwind table already knows gp, no need to specify anything + add r39 = 0, gp // A + .save rp, r36 + mov r36 = rp // I + .vframe r38 + add r38 = 0, sp ;; // A + +// We first calculate the amount of extra memory stack space required +// for the arguments, and register storage. +// We then call invoke_copy_to_stack() to write the argument contents +// to the specified memory regions. +// We then copy the integer arguments to integer registers, and floating +// arguments to float registers. +// Lastly we load the virtual table jump pointer, and call the target +// subroutine. + +// in0 : that +// in1 : methodIndex +// in2 : paramCount +// in3 : params + +// stack frame size is 16 + (8 * even(paramCount)) + 64 + 64 +// 16 byte frame header +// 8 * even(paramCount) memory argument area +// 64 bytes integer register area +// 64 bytes float register area +// This scheme makes sure stack fram size is a multiple of 16 + + .body + add r10 = 8, r0 // A +// r41 points to float register area + add r41 = -64, sp // A +// r40 points to int register area + add r40 = -128, sp ;; // A + + add out1 = 0, r40 // A + add out2 = 0, r41 // A + tbit.z p14,p15 = in2,0 ;; // I + +// compute 8 * even(paramCount) +(p14) shladd r11 = in2, 3, r0 ;; // A +(p15) shladd r11 = in2, 3, r10 ;; // A + sub out0 = r40, r11 ;; // A + +// advance the stack frame + add sp = -16, out0 // A + add out3 = 0, in2 // A + add out4 = 0, in3 // A + +// branch to invoke_copy_to_stack + br.call.sptk.few rp = invoke_copy_to_stack ;; // B + +// restore gp + add gp = 0, r39 // A + add out0 = 0, in0 // A + +// load the integer and float registers + ld8 out1 = [r40], 8 // M + ldfd f8 = [r41], 8 ;; // M + + ld8 out2 = [r40], 8 // M + ldfd f9 = [r41], 8 ;; // M + + ld8 out3 = [r40], 8 // M + ldfd f10 = [r41], 8 ;; // M + + ld8 out4 = [r40], 8 // M + ldfd f11 = [r41], 8 ;; // M + + ld8 out5 = [r40], 8 // M + ldfd f12 = [r41], 8 ;; // M +// 16 * methodIndex + shladd r11 = in1, 4, r0 // A + + ld8 out6 = [r40], 8 // M + ldfd f13 = [r41], 8 ;; // M + + ld8 out7 = [r40], 8 // M + ldfd f14 = [r41], 8 // M + add r8 = 0, in0 ;; // A + +// look up virtual base table and dispatch to target subroutine +// This section assumes 64 bit pointer mode, and virtual base table +// layout from the ABI http://www.codesourcery.com/cxx-abi/abi.html + +// load base table + ld8 r8 = [r8] ;; // M + add r8 = r11, r8 ;; // A + + // first entry is jump pointer, second entry is gp + add r9 = 8, r8 ;; // A +// load jump pointer + ld8 r8 = [r8] + +// load gp + ld8 gp = [r9] ;; // M + mov b6 = r8 ;; // I + +// branch to target virtual function + br.call.sptk.few rp = b6 ;; // B + +// epilog + mov ar.pfs = r37 // I + mov rp = r36 ;; // I + + add sp = 0, r38 // A + add gp = 0, r39 // A + br.ret.sptk.few rp ;; // B + + .endp + + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_irix.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_irix.s new file mode 100644 index 00000000..4e8e0895 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_irix.s @@ -0,0 +1,149 @@ + +#include <sys/regdef.h> +#include <sys/asm.h> + +.text +.globl invoke_count_words +.globl invoke_copy_to_stack + +LOCALSZ=7 # a0, a1, a2, a3, s0, ra, gp +FRAMESZ=(((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK + +RAOFF=FRAMESZ-(1*SZREG) +A0OFF=FRAMESZ-(2*SZREG) +A1OFF=FRAMESZ-(3*SZREG) +A2OFF=FRAMESZ-(4*SZREG) +A3OFF=FRAMESZ-(5*SZREG) +S0OFF=FRAMESZ-(6*SZREG) +GPOFF=FRAMESZ-(7*SZREG) + + # + # _XPTC_InvokeByIndex(that, methodIndex, paramCount, params) + # a0 a1 a2 a3 + +NESTED(_XPTC_InvokeByIndex, FRAMESZ, ra) + SETUP_GP + PTR_SUBU sp, FRAMESZ + SETUP_GP64(GPOFF, _XPTC_InvokeByIndex) + SAVE_GP(GPOFF) + + REG_S ra, RAOFF(sp) + REG_S a0, A0OFF(sp) + REG_S a1, A1OFF(sp) + REG_S a2, A2OFF(sp) + REG_S a3, A3OFF(sp) + REG_S s0, S0OFF(sp) + REG_S gp, GPOFF(sp) + + # invoke_count_words(paramCount, params) + move a0, a2 + move a1, a3 + jal invoke_count_words + + # invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, + # nsXPTCVariant* s, PRUint32 *reg) + + REG_L a1, A2OFF(sp) # a1 - paramCount + REG_L a2, A3OFF(sp) # a2 - params + + # save sp before we copy the params to the stack + move t0, sp + + # assume full size of 8 bytes per param to be safe + sll v0, 4 # 8 bytes * num params + subu sp, sp, v0 # make room + move a0, sp # a0 - param stack address + + # create temporary stack space to write int and fp regs + subu sp, 64 # 64 = 8 regs of 8 bytes + + move a3, sp + + # save the old sp and save the arg stack + subu sp, sp, 16 + REG_S t0, 0(sp) + REG_S a0, 8(sp) + + # copy the param into the stack areas + jal invoke_copy_to_stack + + REG_L t3, 8(sp) # get previous a0 + REG_L sp, 0(sp) # get orig sp back + + REG_L a0, A0OFF(sp) # a0 - that + REG_L a1, A1OFF(sp) # a1 - methodIndex + +#ifdef __GNUC__ + # t1 = methodIndex * 8 + # (use shift instead of mult) + sll t1, a1, 3 +#else + # t1 = methodIndex * 12 + # (use shift and subtract trick instead of mult) + sll t1, a1, 2 + subu t1, t1, a1 + sll t1, t1, 2 +#endif + + # calculate the function we need to jump to, + # which must then be saved in t9 + lw t9, 0(a0) + addu t9, t9, t1 +#ifdef __GNUC__ + lw t9, 12(t9) # t9 = *(that+t1+12) +#else + li t2, 20 + addu t9, t9, t2 + lw t9, 0(t9) # t9 = *(that+t1+20) +#endif + + # calculate the proper "this" pointer for the + # function that they asked for + lw t0, 0(a0) + addu t0, t1 +#ifdef __GNUC__ + lh t0, 8(t0) +#else + lw t0, 12(t0) +#endif + + addu a0, a0, t0 + + # get register save area from invoke_copy_to_stack + subu t1, t3, 64 + + # a1..a7 and f13..f19 should now be set to what + # invoke_copy_to_stack told us. skip a0 and f12 + # because that's the "this" pointer + + REG_L a1, 0(t1) + REG_L a2, 8(t1) + REG_L a3, 16(t1) + REG_L a4, 24(t1) + REG_L a5, 32(t1) + REG_L a6, 40(t1) + REG_L a7, 48(t1) + + l.d $f13, 0(t1) + l.d $f14, 8(t1) + l.d $f15, 16(t1) + l.d $f16, 24(t1) + l.d $f17, 32(t1) + l.d $f18, 40(t1) + l.d $f19, 48(t1) + + # save away our stack pointer and create + # the stack pointer for the function + move s0, sp + move sp, t3 + + jalr ra, t9 + + move sp, s0 + + RESTORE_GP64 + REG_L ra, RAOFF(sp) + REG_L s0, S0OFF(sp) + PTR_ADDU sp, FRAMESZ + j ra +.end _XPTC_InvokeByIndex diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s new file mode 100644 index 00000000..f011aaf5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s @@ -0,0 +1,166 @@ +/* -*- Mode: asm; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp, Inc. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brendan Eich <brendan@mozilla.org> + * Stuart Parmenter <pavlov@netscape.com> + */ + +/* This code is for MIPS using the O32 ABI. */ + +#include <sys/regdef.h> +#include <sys/asm.h> + +.text +.globl invoke_count_words +.globl invoke_copy_to_stack + +# We need a variable number of words allocated from the stack for copies of +# the params, and this space must come between the high frame (where ra, gp, +# and s0 are saved) and the low frame (where a0-a3 are saved by the callee +# functions we invoke). + +LOCALSZ=4 # s0, s1, ra, gp +NARGSAVE=4 # a0, a1, a2, a3 +HIFRAMESZ=(LOCALSZ*SZREG) +LOFRAMESZ=(NARGSAVE*SZREG) +FRAMESZ=(HIFRAMESZ+LOFRAMESZ+ALSZ)&ALMASK + +# XXX these 2*SZREG, etc. are very magic -- we *know* that ALSZ&ALMASK cause +# FRAMESZ to be 0 mod 8, in this case to be 16 and not 12. +RAOFF=FRAMESZ - (2*SZREG) +GPOFF=FRAMESZ - (3*SZREG) +S0OFF=FRAMESZ - (4*SZREG) +S1OFF=FRAMESZ - (5*SZREG) + +# These are not magic -- they are just our argsave slots in the caller frame. +A0OFF=FRAMESZ +A1OFF=FRAMESZ + (1*SZREG) +A2OFF=FRAMESZ + (2*SZREG) +A3OFF=FRAMESZ + (3*SZREG) + + # + # _XPTC_InvokeByIndex(that, methodIndex, paramCount, params) + # a0 a1 a2 a3 + +NESTED(_XPTC_InvokeByIndex, FRAMESZ, ra) + + .set noreorder + .cpload t9 + .set reorder + + subu sp, FRAMESZ + + # specify the save register mask -- XXX do we want the a0-a3 here, given + # our "split" frame where the args are saved below a dynamicly allocated + # region under the high frame? + # + # 10010000000000010000000011110000 + .mask 0x900100F0, -((NARGSAVE+LOCALSZ)*SZREG) + + # thou shalt not use .cprestore if yer frame has variable size... + # .cprestore GPOFF + + REG_S ra, RAOFF(sp) + + # this happens automatically with .cprestore, but we cannot use that op... + REG_S gp, GPOFF(sp) + REG_S s0, S0OFF(sp) + REG_S s1, S1OFF(sp) + + REG_S a0, A0OFF(sp) + REG_S a1, A1OFF(sp) + REG_S a2, A2OFF(sp) + REG_S a3, A3OFF(sp) + + # invoke_count_words(paramCount, params) + move a0, a2 + move a1, a3 + + jal invoke_count_words + lw gp, GPOFF(sp) + + # save the old sp so we can pop the param area and any "low frame" + # needed as an argsave area below the param block for callees that + # we invoke. + move s0, sp + + REG_L a1, A2OFF(sp) # a1 = paramCount + REG_L a2, A3OFF(sp) # a2 = params + + # we define a word as 4 bytes, period end of story! + sll v0, 2 # 4 bytes * result of invoke_copy_words + subu v0, LOFRAMESZ # but we take back the argsave area built into + # our stack frame -- SWEET! + subu sp, sp, v0 # make room + move a0, sp # a0 = param stack address + move s1, a0 # save it for later -- it should be safe here + + # the old sp is still saved in s0, but we now need another argsave + # area ("low frame") for the invoke_copy_to_stack call. + subu sp, sp, LOFRAMESZ + + # copy the param into the stack areas + # invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, + # nsXPTCVariant* s) + jal invoke_copy_to_stack + lw gp, GPOFF(s0) + + move sp, s0 # get orig sp back, popping params and argsave + + REG_L a0, A0OFF(sp) # a0 = set "that" to be "this" + REG_L a1, A1OFF(sp) # a1 = methodIndex + + # t1 = methodIndex * 4 + # (use shift instead of mult) + sll t1, a1, 2 + + # calculate the function we need to jump to, + # which must then be saved in t9 + lw t9, 0(a0) + addu t9, t9, t1 + lw t9, 8(t9) + + # a1..a3 and f13..f14 should now be set to what + # invoke_copy_to_stack told us. skip a0 and f12 + # because that is the "this" pointer + + REG_L a1, 1*SZREG(s1) + REG_L a2, 2*SZREG(s1) + REG_L a3, 3*SZREG(s1) + + l.d $f13, 8(s1) + l.d $f14, 16(s1) + + # Create the stack pointer for the function, which must have 4 words + # of space for callee-saved args. invoke_count_words allocated space + # for a0 starting at s1, so we just move s1 into sp. + move sp, s1 + + jalr ra, t9 + lw gp, GPOFF(s0) + + move sp, s0 + + REG_L ra, RAOFF(sp) + REG_L s0, S0OFF(sp) + addu sp, FRAMESZ + j ra +.end _XPTC_InvokeByIndex diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_openvms_alpha.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_openvms_alpha.s new file mode 100644 index 00000000..d37a91d2 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_openvms_alpha.s @@ -0,0 +1,99 @@ +;* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +;* +;* The contents of this file are subject to the Netscape Public +;* License Version 1.1 (the "License"); you may not use this file +;* except in compliance with the License. You may obtain a copy of +;* the License at http://www.mozilla.org/NPL/ +;* +;* Software distributed under the License is distributed on an "AS +;* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +;* implied. See the License for the specific language governing +;* rights and limitations under the License. +;* +;* The Original Code is mozilla.org code. +;* +;* The Initial Developer of the Original Code is Netscape +;* Communications Corporation. Portions created by Netscape are +;* Copyright (C) 1998 Netscape Communications Corporation. All +;* Rights Reserved. +;* +;* Contributor(s): +;*/ + +; +; XPTC_PUBLIC_API(nsresult) +; XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +; PRUint32 paramCount, nsXPTCVariant* params) +; + + .title "INVOKE" "Invoke By Index" + + $routine XPTC_InvokeByIndex, kind=stack, saved_regs=<R2,R3,R4> + + mov r27,r2 ; Need to set up a base register... + .base r2,$LS ; ...for the LINKAGE_PAIR call + + mov r17,r3 ; save methodIndex in r3 + mov r18,r4 ; save paramCount in r4 + +; +; Allocate enough stack space to hold the greater of 6 or "paramCount"+1 +; parameters. (+1 for "this" pointer) Room for at least 6 parameters +; is required for storage of those passed via registers. +; + + cmplt R18,5,R1 ; paramCount = MAX(5, "paramCount") + cmovne R1,5,R18 + s8addq R18,16,R1 ; room for "paramCount"+1 params (8 bytes each) + bic R1,15,R1 ; stack space is rounded up to 0 % 16 + subq SP,R1,SP + + stq R16,0(SP) ; save "that" (as "this" pointer) + addq SP,8,R16 ; pass stack pointer + mov R4,R17 ; pass original "paramCount + mov R19,R18 ; pass "params" + mov 4,r25 ; argument count + + $LINKAGE_PAIR invoke_copy_to_stack + ldq r26,$LP ; get entry point address from linkage pair + ldq r27,$LP+8 ; get procedure descriptor address from lp + jsr r26,r26 ; and call the routine + +; +; Copy the first 6 parameters to registers and remove from stack frame. +; Both the integer and floating point registers are set for each parameter +; except the first which is the "this" pointer. (integer only) +; The floating point registers are all set as doubles since the +; invoke_copy_to_stack function should have converted the floats. +; + ldq R16,0(SP) ; integer registers + ldq R17,8(SP) + ldq R18,16(SP) + ldq R19,24(SP) + ldq R20,32(SP) + ldq R21,40(SP) + ldt F17,8(SP) ; floating point registers + ldt F18,16(SP) + ldt F19,24(SP) + ldt F20,32(SP) + ldt F21,40(SP) + + addq SP,48,SP ; remove params from stack + +; +; Call the virtual function with the constructed stack frame. +; First three methods are always QueryInterface, AddRef and Release. +; + addq r4,1,r25 ; argument count now includes "this" + mov R16,R1 ; load "this" + ldl R1,0(R1) ; load vtable + s4addq r3,0,r28 ; vtable index = "methodIndex" * 4 + addq r1,r28,r1 + ldl r27,0(r1) ; load procedure value + ldq r26,8(r27) ; load entry point address + jsr r26,r26 ; call virtual function + + $return + + $end_routine XPTC_InvokeByIndex + .end diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_osf1_alpha.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_osf1_alpha.s new file mode 100644 index 00000000..ad7b2f82 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_osf1_alpha.s @@ -0,0 +1,83 @@ +/* + * XPTC_PUBLIC_API(nsresult) + * XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + * PRUint32 paramCount, nsXPTCVariant* params) + */ +.text +.align 4 +.globl XPTC_InvokeByIndex +.ent XPTC_InvokeByIndex +XPTC_InvokeByIndex: +.frame $15,32,$26,0 +.mask 0x4008000,-32 +ldgp $29,0($27) +XPTC_InvokeByIndexXv: +subq $30,32,$30 +stq $26,0($30) +stq $15,8($30) +bis $30,$30,$15 +.prologue 1 + +/* + * Allocate enough stack space to hold the greater of 6 or "paramCount"+1 + * parameters. (+1 for "this" pointer) Room for at least 6 parameters + * is required for storage of those passed via registers. + */ + +bis $31,5,$2 /* count = MAX(5, "paramCount") */ +cmplt $2,$18,$1 +cmovne $1,$18,$2 +s8addq $2,16,$1 /* room for count+1 params (8 bytes each) */ +bic $1,15,$1 /* stack space is rounded up to 0 % 16 */ +subq $30,$1,$30 + +stq $16,0($30) /* save "that" (as "this" pointer) */ +stq $17,16($15) /* save "methodIndex" */ + +addq $30,8,$16 /* pass stack pointer */ +bis $18,$18,$17 /* pass "paramCount" */ +bis $19,$19,$18 /* pass "params" */ +jsr $26,invoke_copy_to_stack /* call invoke_copy_to_stack */ +ldgp $29,0($26) + +/* + * Copy the first 6 parameters to registers and remove from stack frame. + * Both the integer and floating point registers are set for each parameter + * except the first which is the "this" pointer. (integer only) + * The floating point registers are all set as doubles since the + * invoke_copy_to_stack function should have converted the floats. + */ +ldq $16,0($30) /* integer registers */ +ldq $17,8($30) +ldq $18,16($30) +ldq $19,24($30) +ldq $20,32($30) +ldq $21,40($30) +ldt $f17,8($30) /* floating point registers */ +ldt $f18,16($30) +ldt $f19,24($30) +ldt $f20,32($30) +ldt $f21,40($30) + +addq $30,48,$30 /* remove params from stack */ + +/* + * Call the virtual function with the constructed stack frame. + */ +bis $16,$16,$1 /* load "this" */ +ldq $2,16($15) /* load "methodIndex" */ +ldq $1,0($1) /* load vtable */ +s8addq $2,0,$2 /* vtable index = "methodIndex" * 8 + 16 */ +addq $1,$2,$1 +ldq $27,0($1) /* load address of function */ +jsr $26,($27),0 /* call virtual function */ +ldgp $29,0($26) + +bis $15,$15,$30 +ldq $26,0($30) +ldq $15,8($30) +addq $30,32,$30 +ret $31,($26),1 +.end XPTC_InvokeByIndex + + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_pa32.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_pa32.s new file mode 100644 index 00000000..8ce8f17f --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_pa32.s @@ -0,0 +1,131 @@ + .LEVEL 1.1 +framesz .EQU 128 + +; XPTC_InvokeByIndex(nsISuppots* that, PRUint32 methodIndex, +; PRUint32 paramCount, nsXPTCVariant* params); + +; g++ need to compile everything with -fvtable-thunks ! + + .SPACE $TEXT$,SORT=8 + .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24 +XPTC_InvokeByIndex + .PROC + .CALLINFO CALLER,FRAME=72,ENTRY_GR=%r3,SAVE_RP,SAVE_SP,ARGS_SAVED,ALLOCA_FRAME + + ; frame marker takes 48 bytes, + ; register spill area takes 8 bytes, + ; local stack area takes 72 bytes result in 128 bytes total + + .ENTRY + STW %rp,-20(%sp) + STW,MA %r3,128(%sp) + + LDO -framesz(%r30),%r28 + STW %r28,-4(%r30) ; save previous sp + STW %r19,-32(%r30) + + STW %r26,-36-framesz(%r30) ; save argument registers in + STW %r25,-40-framesz(%r30) ; in PREVIOUS frame + STW %r24,-44-framesz(%r30) ; + STW %r23,-48-framesz(%r30) ; + + B,L .+8,%r2 + ADDIL L'invoke_count_bytes-$PIC_pcrel$1+4,%r2,%r1 + LDO R'invoke_count_bytes-$PIC_pcrel$2+8(%r1),%r1 +$PIC_pcrel$1 + LDSID (%r1),%r31 +$PIC_pcrel$2 + MTSP %r31,%sr0 + .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR ;in=24,25,26;out=28 + BE,L 0(%sr0,%r1),%r31 + COPY %r31,%r2 + + CMPIB,>= 0,%r28, .+76 + COPY %r30,%r3 ; copy stack ptr to saved stack ptr + ADD %r30,%r28,%r30 ; extend stack frame + LDW -4(%r3),%r28 ; move frame + STW %r28,-4(%r30) + LDW -8(%r3),%r28 + STW %r28,-8(%r30) + LDW -12(%r3),%r28 + STW %r28,-12(%r30) + LDW -16(%r3),%r28 + STW %r28,-16(%r30) + LDW -20(%r3),%r28 + STW %r28,-20(%r30) + LDW -24(%r3),%r28 + STW %r28,-24(%r30) + LDW -28(%r3),%r28 + STW %r28,-28(%r30) + LDW -32(%r3),%r28 + STW %r28,-32(%r30) + + LDO -40(%r30),%r26 ; load copy address + LDW -44-framesz(%r3),%r25 ; load rest of 2 arguments + LDW -48-framesz(%r3),%r24 ; + + LDW -32(%r30),%r19 ; shared lib call destroys r19; reload + B,L .+8,%r2 + ADDIL L'invoke_copy_to_stack-$PIC_pcrel$3+4,%r2,%r1 + LDO R'invoke_copy_to_stack-$PIC_pcrel$4+8(%r1),%r1 +$PIC_pcrel$3 + LDSID (%r1),%r31 +$PIC_pcrel$4 + MTSP %r31,%sr0 + .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR ;in=24,25,26 + BE,L 0(%sr0,%r1),%r31 + COPY %r31,%r2 + + LDO -48(%r30),%r20 + EXTRW,U,= %r28,31,1,%r22 + FLDD 0(%r20),%fr7 ; load double arg 1 + EXTRW,U,= %r28,30,1,%r22 + FLDW 8(%r20),%fr5L ; load float arg 1 + EXTRW,U,= %r28,29,1,%r22 + FLDW 4(%r20),%fr6L ; load float arg 2 + EXTRW,U,= %r28,28,1,%r22 + FLDW 0(%r20),%fr7L ; load float arg 3 + + LDW -36-framesz(%r3),%r26 ; load ptr to 'that' + LDW -40(%r30),%r25 ; load the rest of dispatch argument registers + LDW -44(%r30),%r24 + LDW -48(%r30),%r23 + + LDW -36-framesz(%r3),%r20 ; load vtable addr + LDW -40-framesz(%r3),%r28 ; load index + LDW 0(%r20),%r20 ; follow vtable + LDO 16(%r20),%r20 ; offset vtable by 16 bytes (g++: 8, aCC: 16) + SH2ADDL %r28,%r20,%r28 ; add 4*index to vtable entry + LDW 0(%r28),%r22 ; load vtable entry + + B,L .+8,%r2 + ADDIL L'$$dyncall_external-$PIC_pcrel$5+4,%r2,%r1 + LDO R'$$dyncall_external-$PIC_pcrel$6+8(%r1),%r1 +$PIC_pcrel$5 + LDSID (%r1),%r31 +$PIC_pcrel$6 + MTSP %r31,%sr0 + .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR +;in=22-26;out=28; + BE,L 0(%sr0,%r1),%r31 + COPY %r31,%r2 + + LDW -32(%r30),%r19 + COPY %r3,%r30 ; restore saved stack ptr + + LDW -148(%sp),%rp + BVE (%rp) + .EXIT + LDW,MB -128(%sp),%r3 + + .PROCEND ;in=23,24,25,26; + + .ALIGN 8 + .SPACE $TEXT$ + .SUBSPA $CODE$ + .IMPORT $$dyncall_external,MILLICODE + .IMPORT invoke_count_bytes,CODE + .IMPORT invoke_copy_to_stack,CODE + .EXPORT XPTC_InvokeByIndex,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN + .END + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix.s new file mode 100644 index 00000000..3684d154 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix.s @@ -0,0 +1,146 @@ + # + # -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + # + # The contents of this file are subject to the Netscape Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/NPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is mozilla.org code. + # + # The Initial Developer of the Original Code is Netscape + # Communications Corporation. Portions created by Netscape are + # Copyright (C) 1999 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): + # IBM Corporation + # + +.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 +.set BO_IF,12 +.set CR0_EQ,2 + + + + .rename H.10.NO_SYMBOL{PR},"" + .rename H.18.XPTC_InvokeByIndex{TC},"XPTC_InvokeByIndex" + + +# .text section + + .csect H.10.NO_SYMBOL{PR} + .globl .XPTC_InvokeByIndex + .globl XPTC_InvokeByIndex{DS} + .extern .invoke_copy_to_stack + .extern ._ptrgl{PR} + + +# +# XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +# PRUint32 paramCount, nsXPTCVariant* params) +# + +.XPTC_InvokeByIndex: + mflr r0 + stw r31,-4(sp) +# +# save off the incoming values in the caller's parameter area +# + stw r3,24(sp) # that + stw r4,28(sp) # methodIndex + stw r5,32(sp) # paramCount + stw r6,36(sp) # params + stw r0,8(sp) + stwu sp,-136(sp) # = 24 for linkage area, 8 * 13 for fprData area, 8 for saved registers + +# prepare args for 'invoke_copy_to_stack' call +# + lwz r4,168(sp) # paramCount + lwz r5,172(sp) # params + mr r6,sp # fprData + slwi r3,r4,3 # number of bytes of stack required + # at most 8*paramCount + addi r3,r3,28 # linkage area + mr r31,sp # save original stack top + subfc sp,r3,sp # bump the stack + addi r3,sp,28 # parameter pointer excludes linkage area size + 'this' + + bl .invoke_copy_to_stack + nop + + lfd f1,0(r31) # Restore floating point registers + lfd f2,8(r31) + lfd f3,16(r31) + lfd f4,24(r31) + lfd f5,32(r31) + lfd f6,40(r31) + lfd f7,48(r31) + lfd f8,56(r31) + lfd f9,64(r31) + lfd f10,72(r31) + lfd f11,80(r31) + lfd f12,88(r31) + lfd f13,96(r31) + + lwz r3,160(r31) # that + lwz r4,0(r3) # get vTable from 'that' + lwz r5,164(r31) # methodIndex + slwi r5,r5,3 # methodIndex * 8 + addi r5,r5,8 # step over junk at start of vTable ! + lwzx r11,r5,r4 # get function pointer + + addi r5,r5,4 # We need to manually adjust the 'that' pointer, this is CFRONT based + lwzx r5,r4,r5 # offset = r4(vtable) + r5(methodIndex offset) - 4 + add r3,r5,r3 # adjust 'that' r3 = r3 + r5 + + lwz r4,28(sp) + lwz r5,32(sp) + lwz r6,36(sp) + lwz r7,40(sp) + lwz r8,44(sp) + lwz r9,48(sp) + lwz r10,52(sp) + + bl ._ptrgl{PR} + nop + + mr sp,r31 + lwz r0,144(sp) + addi sp,sp,136 + mtlr r0 + lwz r31,-4(sp) + blr + + +# .data section + + .toc # 0x00000038 +T.18.XPTC_InvokeByIndex: + .tc H.18.XPTC_InvokeByIndex{TC},XPTC_InvokeByIndex{DS} + + .csect XPTC_InvokeByIndex{DS} + .long .XPTC_InvokeByIndex # "\0\0\0\0" + .long TOC{TC0} # "\0\0\0008" + .long 0x00000000 # "\0\0\0\0" +# End csect XPTC_InvokeByIndex{DS} + +# .bss section diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix64.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix64.s new file mode 100644 index 00000000..a174e424 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix64.s @@ -0,0 +1,161 @@ +# ***** BEGIN LICENSE BLOCK ***** +# +# Version: MPL 1.1/LGPL 2.1/GPL 2.0 +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is IBM Corporation. +# Portions created by IBM are +# Copyright (C) 2002, International Business Machines Corporation. +# All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the LGPL or the GPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 +.set BO_IF,12 +.set CR0_EQ,2 + + .rename H.10.NO_SYMBOL{PR},"" + .rename H.18.XPTC_InvokeByIndex{TC},"XPTC_InvokeByIndex" + + +# .text section + + .csect H.10.NO_SYMBOL{PR} + .globl .XPTC_InvokeByIndex + .globl XPTC_InvokeByIndex{DS} + .extern .invoke_copy_to_stack + .extern ._ptrgl{PR} + +# +# XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +# PRUint32 paramCount, nsXPTCVariant* params) +# + +.XPTC_InvokeByIndex: + mflr r0 + std r31,-8(sp) +# +# save off the incoming values in the caller's parameter area +# + std r3,48(sp) # that + std r4,56(sp) # methodIndex + std r5,64(sp) # paramCount + std r6,72(sp) # params + std r0,16(sp) + stdu sp,-168(sp) # 2*24=48 for linkage area, + # 8*13=104 for fprData area + # 16 for saved registers + +# prepare args for 'invoke_copy_to_stack' call +# + ld r4,232(sp) # paramCount (168+8+56) + ld r5,240(sp) # params + mr r6,sp # fprData + sldi r3,r4,3 # number of bytes of stack required + # is at most numParams*8 + addi r3,r3,56 # linkage area (48) + this (8) + mr r31,sp # save original stack top + subfc sp,r3,sp # bump the stack + addi r3,sp,56 # parameter pointer excludes linkage area + # size + 'this' + + bl .invoke_copy_to_stack + nop + + lfd f1,0(r31) # Restore floating point registers + lfd f2,8(r31) + lfd f3,16(r31) + lfd f4,24(r31) + lfd f5,32(r31) + lfd f6,40(r31) + lfd f7,48(r31) + lfd f8,56(r31) + lfd f9,64(r31) + lfd f10,72(r31) + lfd f11,80(r31) + lfd f12,88(r31) + lfd f13,96(r31) + + ld r3,216(r31) # that (168+48) + ld r4,0(r3) # get vTable from 'that' + ld r5,224(r31) # methodIndex (168+56) + sldi r5,r5,3 # methodIndex * 8 + # No junk at the start of 64bit vtable !!! + ldx r11,r5,r4 # get function pointer (this jumps + # either to the function if no adjustment + # is needed (displacement = 0), or it + # jumps to the thunk code, which will jump + # to the function at the end) + + # No adjustment of the that pointer in 64bit mode, this is done + # by the thunk code + + ld r4,56(sp) + ld r5,64(sp) + ld r6,72(sp) + ld r7,80(sp) + ld r8,88(sp) + ld r9,96(sp) + ld r10,104(sp) + + bl ._ptrgl{PR} + nop + + mr sp,r31 + ld r0,184(sp) # 168+16 + addi sp,sp,168 + mtlr r0 + ld r31,-8(sp) + blr + +# .data section + + .toc # 0x00000038 +T.18.XPTC_InvokeByIndex: + .tc H.18.XPTC_InvokeByIndex{TC},XPTC_InvokeByIndex{DS} + + .csect XPTC_InvokeByIndex{DS} + .llong .XPTC_InvokeByIndex # "\0\0\0\0" + .llong TOC{TC0} # "\0\0\0008" + .llong 0x00000000 # "\0\0\0\0" +# End csect XPTC_InvokeByIndex{DS} + +# .bss section diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_ibmobj_aix.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_ibmobj_aix.s new file mode 100644 index 00000000..064a73ab --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_ibmobj_aix.s @@ -0,0 +1,140 @@ + # + # -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + # + # The contents of this file are subject to the Netscape Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/NPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is mozilla.org code. + # + # The Initial Developer of the Original Code is IBM Corporation. + # Portions created by IBM are + # Copyright (C) 2004, International Business Machines Corporation. + # All Rights Reserved. + # + # Contributor(s): + # + +.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 +.set BO_IF,12 +.set CR0_EQ,2 + + + + .rename H.10.NO_SYMBOL{PR},"" + .rename H.18.XPTC_InvokeByIndex{TC},"XPTC_InvokeByIndex" + + +# .text section + + .csect H.10.NO_SYMBOL{PR} + .globl .XPTC_InvokeByIndex + .globl XPTC_InvokeByIndex{DS} + .extern .invoke_copy_to_stack + .extern ._ptrgl{PR} + + +# +# XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +# PRUint32 paramCount, nsXPTCVariant* params) +# + +.XPTC_InvokeByIndex: + mflr r0 + stw r31,-4(sp) +# +# save off the incoming values in the caller's parameter area +# + stw r3,24(sp) # that + stw r4,28(sp) # methodIndex + stw r5,32(sp) # paramCount + stw r6,36(sp) # params + stw r0,8(sp) + stwu sp,-136(sp) # = 24 for linkage area, 8 * 13 for fprData area, 8 for saved registers + +# prepare args for 'invoke_copy_to_stack' call +# + lwz r4,168(sp) # paramCount + lwz r5,172(sp) # params + mr r6,sp # fprData + slwi r3,r4,3 # number of bytes of stack required + # at most 8*paramCount + addi r3,r3,28 # linkage area + mr r31,sp # save original stack top + subfc sp,r3,sp # bump the stack + addi r3,sp,28 # parameter pointer excludes linkage area size + 'this' + + bl .invoke_copy_to_stack + nop + + lfd f1,0(r31) # Restore floating point registers + lfd f2,8(r31) + lfd f3,16(r31) + lfd f4,24(r31) + lfd f5,32(r31) + lfd f6,40(r31) + lfd f7,48(r31) + lfd f8,56(r31) + lfd f9,64(r31) + lfd f10,72(r31) + lfd f11,80(r31) + lfd f12,88(r31) + lfd f13,96(r31) + + lwz r3,160(r31) # that + lwz r4,0(r3) # get vTable from 'that' + lwz r5,164(r31) # methodIndex + slwi r5,r5,2 # methodIndex * 4 + lwzx r11,r5,r4 # get function pointer + + lwz r4,28(sp) + lwz r5,32(sp) + lwz r6,36(sp) + lwz r7,40(sp) + lwz r8,44(sp) + lwz r9,48(sp) + lwz r10,52(sp) + + bl ._ptrgl{PR} + nop + + mr sp,r31 + lwz r0,144(sp) + addi sp,sp,136 + mtlr r0 + lwz r31,-4(sp) + blr + + +# .data section + + .toc # 0x00000038 +T.18.XPTC_InvokeByIndex: + .tc H.18.XPTC_InvokeByIndex{TC},XPTC_InvokeByIndex{DS} + + .csect XPTC_InvokeByIndex{DS} + .long .XPTC_InvokeByIndex # "\0\0\0\0" + .long TOC{TC0} # "\0\0\0008" + .long 0x00000000 # "\0\0\0\0" +# End csect XPTC_InvokeByIndex{DS} + +# .bss section diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_linux.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_linux.s new file mode 100644 index 00000000..b9aaa997 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_linux.s @@ -0,0 +1,113 @@ +// -*- Mode: Asm -*- +// +// The contents of this file are subject to the Netscape Public +// License Version 1.1 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of +// the License at http://www.mozilla.org/NPL/ +// +// Software distributed under the License is distributed on an "AS +// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +// implied. See the License for the specific language governing +// rights and limitations under the License. +// +// The Original Code is mozilla.org code. +// +// The Initial Developer of the Original Code is Netscape +// Communications Corporation. Portions created by Netscape are +// Copyright (C) 1999 Netscape Communications Corporation. All +// Rights Reserved. +// +// Contributor(s): +// Franz.Sirl-kernel@lauterbach.com (Franz Sirl) +// beard@netscape.com (Patrick Beard) +// waterson@netscape.com (Chris Waterson) +// + +.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 + + .section ".text" + .align 2 + .globl XPTC_InvokeByIndex + .type XPTC_InvokeByIndex,@function + +// +// XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +// PRUint32 paramCount, nsXPTCVariant* params) +// + +XPTC_InvokeByIndex: + stwu sp,-32(sp) // setup standard stack frame + mflr r0 // save LR + stw r3,8(sp) // r3 <= that + stw r4,12(sp) // r4 <= methodIndex + stw r30,16(sp) + stw r31,20(sp) + + stw r0,36(sp) // store LR backchain + mr r31,sp + + rlwinm r10,r5,3,0,27 // r10 = (ParamCount * 2 * 4) & ~0x0f + addi r0,r10,96 // reserve stack for GPR and FPR register save area r0 = r10 + 96 + lwz r9,0(sp) // r9 = backchain + neg r0,r0 + stwux r9,sp,r0 // reserve stack space and save SP backchain + + addi r3,sp,8 // r3 <= args + mr r4,r5 // r4 <= paramCount + mr r5,r6 // r5 <= params + add r6,r3,r10 // r6 <= gpregs ( == args + r10 ) + mr r30,r6 // store in r30 for use later... + addi r7,r6,32 // r7 <= fpregs ( == gpregs + 32 ) + + bl invoke_copy_to_stack@local // (args, paramCount, params, gpregs, fpregs) + + lfd f1,32(r30) // load FP registers with method parameters + lfd f2,40(r30) + lfd f3,48(r30) + lfd f4,56(r30) + lfd f5,64(r30) + lfd f6,72(r30) + lfd f7,80(r30) + lfd f8,88(r30) + + lwz r3,8(r31) // r3 <= that + lwz r4,12(r31) // r4 <= methodIndex + lwz r5,0(r3) // r5 <= vtable ( == *that ) +#if !((__GNUC__ == 3 && __GNUC_MINOR__ < 2) || __GXX_ABI_VERSION >= 100) // G++ pre-V3 ABI + addi r4,r4,2 // skip first two vtable entries +#endif + slwi r4,r4,2 // convert to offset ( *= 4 ) + lwzx r0,r5,r4 // r0 <= methodpointer ( == vtable + offset ) + + lwz r4,4(r30) // load GP regs with method parameters + lwz r5,8(r30) + lwz r6,12(r30) + lwz r7,16(r30) + lwz r8,20(r30) + lwz r9,24(r30) + lwz r10,28(r30) + + mtlr r0 // copy methodpointer to LR + blrl // call method + + lwz r30,16(r31) // restore r30 & r31 + lwz r31,20(r31) + + lwz r11,0(sp) // clean up the stack + lwz r0,4(r11) + mtlr r0 + mr sp,r11 + blr diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_netbsd.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_netbsd.s new file mode 100644 index 00000000..18c775a9 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_netbsd.s @@ -0,0 +1,114 @@ +# -*- Mode: Asm -*- +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1999 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# Franz.Sirl-kernel@lauterbach.com (Franz Sirl) +# beard@netscape.com (Patrick Beard) +# waterson@netscape.com (Chris Waterson) +# +.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 + + .section ".text" + .align 2 + .globl XPTC_InvokeByIndex + .type XPTC_InvokeByIndex,@function + +# +# XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +# PRUint32 paramCount, nsXPTCVariant* params) +# + +XPTC_InvokeByIndex: + stwu sp,-32(sp) # setup standard stack frame + mflr r0 # save LR + stw r3,8(sp) # r3 <= that + stw r4,12(sp) # r4 <= methodIndex + stw r30,16(sp) + stw r31,20(sp) + + stw r0,36(sp) # store LR backchain + mr r31,sp + + rlwinm r10,r5,3,0,27 # r10 = (ParamCount * 2 * 4) & ~0x0f + addi r0,r10,96 # reserve stack for GPR and FPR register save area r0 = r10 + 96 + lwz r9,0(sp) # r9 = backchain + neg r0,r0 + stwux r9,sp,r0 # reserve stack sapce and save SP backchain + + addi r3,sp,8 # r3 <= args + mr r4,r5 # r4 <= paramCount + mr r5,r6 # r5 <= params + add r6,r3,r10 # r6 <= gpregs ( == args + r10 ) + mr r30,r6 # store in r30 for use later... + addi r7,r6,32 # r7 <= fpregs ( == gpregs + 32 ) + + bl invoke_copy_to_stack@local # (args, paramCount, params, gpregs, fpregs) + + lfd f1,32(r30) # load FP registers with method parameters + lfd f2,40(r30) + lfd f3,48(r30) + lfd f4,56(r30) + lfd f5,64(r30) + lfd f6,72(r30) + lfd f7,80(r30) + lfd f8,88(r30) + + lwz r3,8(r31) # r3 <= that + lwz r4,12(r31) # r4 <= methodIndex + lwz r5,0(r3) # r5 <= vtable ( == *that ) + slwi r4,r4,3 # convert to offset ( *= 8 ) + addi r4,r4,8 # skip first two vtable entries + add r4,r4,r5 + lhz r0,0(r4) # virtual base offset + extsh r0,r0 + add r3,r3,r0 + lwz r0,4(r4) # r0 <= methodpointer ( == vtable + offset ) + + lwz r4,4(r30) # load GP regs with method parameters + lwz r5,8(r30) + lwz r6,12(r30) + lwz r7,16(r30) + lwz r8,20(r30) + lwz r9,24(r30) + lwz r10,28(r30) + + mtlr r0 # copy methodpointer to LR + blrl # call method + + lwz r30,16(r31) # restore r30 & r31 + lwz r31,20(r31) + + lwz r11,0(sp) # clean up the stack + lwz r0,4(r11) + mtlr r0 + mr sp,r11 + blr diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_rhapsody.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_rhapsody.s new file mode 100644 index 00000000..8a5c9afb --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_rhapsody.s @@ -0,0 +1,162 @@ +# +# -*- Mode: Asm -*- +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1999 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# Patrick C. Beard <beard@netscape.com> +# + +# +# ** Assumed vtable layout (obtained by disassembling with gdb): +# ** 4 bytes per vtable entry, skip 0th and 1st entries, so the mapping +# ** from index to entry is (4 * index) + 8. +# + +.text + .align 2 +# +# XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, +# PRUint32 paramCount, nsXPTCVariant* params) +# + +.globl __XPTC_InvokeByIndex +__XPTC_InvokeByIndex: + mflr r0 + stw r31,-4(r1) +# +# save off the incoming values in the callers parameter area +# + stw r3,24(r1) ; that + stw r4,28(r1) ; methodIndex + stw r5,32(r1) ; paramCount + stw r6,36(r1) ; params + stw r0,8(r1) + stwu r1,-144(r1) ; 24 for linkage area, + ; 8*13 for fprData area, + ; 8 for saved registers, + ; 8 to keep stack 16-byte aligned + +# set up for and call 'invoke_count_words' to get new stack size +# + mr r3,r5 + mr r4,r6 + + stwu r1,-24(r1) + bl L_invoke_count_words$stub + lwz r1,0(r1) + +# prepare args for 'invoke_copy_to_stack' call +# + lwz r4,176(r1) ; paramCount + lwz r5,180(r1) ; params + mr r6,r1 ; fprData + slwi r3,r3,2 ; number of stack bytes required + addi r3,r3,28 ; linkage area + mr r31,r1 ; save original stack top + sub r1,r1,r3 ; bump the stack + clrrwi r1,r1,4 ; keep the stack 16-byte aligned + addi r3,r31,144 ; act like real alloca, so 0(sp) always + stw r3,0(r1) ; points back to previous stack frame + addi r3,r1,28 ; parameter pointer excludes linkage area size + 'this' + +# create "temporary" stack frame for _invoke_copy_to_stack to operate in. + stwu r1,-40(r1) + bl L_invoke_copy_to_stack$stub +# remove temporary stack frame. + lwz r1,0(r1) + + lfd f1,0(r31) + lfd f2,8(r31) + lfd f3,16(r31) + lfd f4,24(r31) + lfd f5,32(r31) + lfd f6,40(r31) + lfd f7,48(r31) + lfd f8,56(r31) + lfd f9,64(r31) + lfd f10,72(r31) + lfd f11,80(r31) + lfd f12,88(r31) + lfd f13,96(r31) + + lwz r3,168(r31) ; that + lwz r4,0(r3) ; get vTable from 'that' + lwz r5,172(r31) ; methodIndex + slwi r5,r5,2 ; methodIndex * 4 +#ifndef HAVE_GCC3_ABI + addi r5,r5,8 ; (methodIndex * 4) + 8 +#endif + lwzx r12,r5,r4 ; get function pointer + + lwz r4,28(r1) + lwz r5,32(r1) + lwz r6,36(r1) + lwz r7,40(r1) + lwz r8,44(r1) + lwz r9,48(r1) + lwz r10,52(r1) + + mtlr r12 + blrl + + mr r1,r31 + lwz r0,152(r1) + addi r1,r1,144 + mtlr r0 + lwz r31,-4(r1) + + blr + +.picsymbol_stub +L_invoke_count_words$stub: + .indirect_symbol _invoke_count_words + mflr r0 + bcl 20,31,L1$pb +L1$pb: + mflr r11 + addis r11,r11,ha16(L1$lz-L1$pb) + mtlr r0 + lwz r12,lo16(L1$lz-L1$pb)(r11) + mtctr r12 + addi r11,r11,lo16(L1$lz-L1$pb) + bctr +.lazy_symbol_pointer +L1$lz: + .indirect_symbol _invoke_count_words + .long dyld_stub_binding_helper + + +.picsymbol_stub +L_invoke_copy_to_stack$stub: + .indirect_symbol _invoke_copy_to_stack + mflr r0 + bcl 20,31,L2$pb +L2$pb: + mflr r11 + addis r11,r11,ha16(L2$lz-L2$pb) + mtlr r0 + lwz r12,lo16(L2$lz-L2$pb)(r11) + mtctr r12 + addi r11,r11,lo16(L2$lz-L2$pb) + bctr +.lazy_symbol_pointer +L2$lz: + .indirect_symbol _invoke_copy_to_stack + .long dyld_stub_binding_helper + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_bsdos.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_bsdos.s new file mode 100644 index 00000000..b744ee9b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_bsdos.s @@ -0,0 +1,121 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): Chris Torek (torek@bsdi.com), Kurt Lidl (lidl@pix.net) + */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + .global XPTC_InvokeByIndex +/* + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +*/ +XPTC_InvokeByIndex: + /* regular C/C++ stack frame -- see <machine/frame.h> */ + save %sp, -96, %sp + + /* + * invoke_count_words(paramCount, params) apparently tells us + * how many "32-bit words" are involved in passing the given + * parameters to the target function. + */ + mov %i2, %o0 + call invoke_count_words ! invoke_count_words(paramCount, params) + mov %i3, %o1 + + /* + * ??? Torek wonders: does invoke_count_words always force its + * return value to be even? If not, we would have to adjust + * the return value ... should make it a multiple of 8 anyway, + * for efficiency (32 byte cache lines); will do that here thus: + * + * We already have room (in our callee's "argument dump" area, + * sp->fr_argd) for six parameters, and we are going to use + * five of those (fr_argd[1] through fr_argd[5]) in a moment. + * This space is followed by fr_argx[1], room for a seventh. + * Thus, if invoke_count_words returns a value between 0 and 6 + * inclusive, we do not need any stack adjustment. For values + * from 7 through (7+8) we want to make room for another 8 + * parameters, and so on. Thus, we want to calculate: + * + * n_extra_words = (wordcount + 1) & ~7 + * + * and then make room for that many more 32-bit words. (Normally + * it would be ((w+7)&~7; we just subtract off the room-for-6 we + * already have.) + */ + inc %o0 + andn %o0, 7, %o0 + sll %o0, 2, %o0 ! convert to bytes + sub %sp, %o0, %sp ! and make room for arguments + + /* + * Copy all the arguments to the stack, starting at the argument + * dump area at [%sp + 68], even though the first six arguments + * go in the six %o registers. We will just load up those + * arguments after the copy is done. The first argument to + * any C++ member function is always the "this" parameter so + * we actually start with what will go in %o1, at [%sp + 72]. + */ + add %sp, 72, %o0 ! invoke_copy_to_stack(addr, + mov %i2, %o1 ! paramCount, + call invoke_copy_to_stack + mov %i3, %o2 ! params); + + /* + * This is the only really tricky (compiler-dependent) part + * (everything else here relies only on the V8 SPARC calling + * conventions). "methodIndex" (%i1) is an index into a C++ + * vtable. The word at "*that" points to the vtable, but for + * some reason, the first function (index=0) is at vtable[2*4], + * the second (index 1) at vtable[3*4], the third at vtable[4*4], + * and so on. Thus, we want, in effect: + * + * that->vTable[index + 2] + */ + ld [%i0], %l0 ! vTable = *that + add %i1, 2, %l1 + sll %l1, 2, %l1 + ld [%l0 + %l1], %l0 ! fn = vTable[index + 2] + + /* + * Now load up the various function parameters. We do not know, + * nor really care, how many there are -- we just load five words + * from the stack (there are always at least five such words to + * load, even if some of them are junk) into %o1 through %o5, + * and set %o0 = %i0, to pass "that" to the target member function + * as its C++ "this" parameter. + * + * If there are more than five parameters, any extras go on our + * stack starting at sp->fr_argx ([%sp + 92]), which is of course + * where we have just copied them. + */ + ld [%sp + 72], %o1 + ld [%sp + 76], %o2 + ld [%sp + 80], %o3 + ld [%sp + 84], %o4 + ld [%sp + 88], %o5 + call %l0 ! fn(that, %o1, %o2, %o3, %o4, %o5) + mov %i0, %o0 + + ! return whatever fn() returned + ret + restore %o0, 0, %o0 + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_linux.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_linux.s new file mode 100644 index 00000000..c23fd1e7 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_linux.s @@ -0,0 +1,67 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + .global XPTC_InvokeByIndex +/* + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +*/ +XPTC_InvokeByIndex: + save %sp,-(64 + 16),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 16 + 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 +! + add %i1,1,%i1 ! vTable is zero-based, index is 1 based (?) + ld [%i0],%l1 ! *that --> vTable + sll %i1,2,%i1 ! 32 bit pointer + add %i1,%l1,%l1 ! vTable[index * 4], l1 now points to vTable entry + ld [%l1 + 4],%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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_linux_GCC3.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_linux_GCC3.s new file mode 100644 index 00000000..9a6b02ae --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_linux_GCC3.s @@ -0,0 +1,84 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * David S. Miller <davem@redhat.com> (ported to gcc3) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + */ + +/* + * Platform specific code to invoke XPCOM methods on native objects for + * Linux/Sparc with gcc 3 ABI. + */ + .global XPTC_InvokeByIndex +/* + * XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + * PRUint32 paramCount, nsXPTCVariant* params); + * + */ +XPTC_InvokeByIndex: + save %sp,-(64 + 16),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 16 + 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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_netbsd.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_netbsd.s new file mode 100644 index 00000000..be0e34a7 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_netbsd.s @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + .global XPTC_InvokeByIndex +/* + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +*/ +XPTC_InvokeByIndex: + save %sp,-(64 + 16),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 16 + 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 +! + add %i1,1,%i1 ! vTable is zero-based, index is 1 based (?) + ld [%i0],%l1 ! *that --> vTable + sll %i1,3,%i1 + add %i1,%l1,%l1 ! vTable[index * 8], l1 now points to vTable entry + lduh [%l1],%l0 ! this adjustor + sll %l0,16,%l0 ! sign extend to 32 bits + sra %l0,16,%l0 + add %l0,%i0,%i0 ! adjust this + ld [%l1 + 4],%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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris.s new file mode 100644 index 00000000..be0e34a7 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris.s @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + .global XPTC_InvokeByIndex +/* + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +*/ +XPTC_InvokeByIndex: + save %sp,-(64 + 16),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 16 + 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 +! + add %i1,1,%i1 ! vTable is zero-based, index is 1 based (?) + ld [%i0],%l1 ! *that --> vTable + sll %i1,3,%i1 + add %i1,%l1,%l1 ! vTable[index * 8], l1 now points to vTable entry + lduh [%l1],%l0 ! this adjustor + sll %l0,16,%l0 ! sign extend to 32 bits + sra %l0,16,%l0 + add %l0,%i0,%i0 ! adjust this + ld [%l1 + 4],%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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_GCC.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_GCC.s new file mode 100644 index 00000000..203e3f1c --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_GCC.s @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + .global XPTC_InvokeByIndex +/* + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +*/ +XPTC_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 +! + add %i1,1,%i1 ! vTable is zero-based, index is 1 based (?) + ld [%i0],%l1 ! *that --> vTable + sll %i1,3,%i1 + add %i1,%l1,%l1 ! vTable[index * 8], l1 now points to vTable entry + lduh [%l1],%l0 ! this adjustor + sll %l0,16,%l0 ! sign extend to 32 bits + sra %l0,16,%l0 + add %l0,%i0,%i0 ! adjust this + ld [%l1 + 4],%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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s new file mode 100644 index 00000000..6a2e9606 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * David Baron <dbaron@dbaron.org> (ported to + * gcc 3/sparc-sun-solaris from gcc 2.x/sparc-sun-solaris) + */ + +/* + * Platform specific code to invoke XPCOM methods on native objects for + * solaris/sparc with gcc 3 ABI. + */ + .global XPTC_InvokeByIndex +/* + * XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + * PRUint32 paramCount, nsXPTCVariant* params); + */ +XPTC_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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_SUNW.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_SUNW.s new file mode 100644 index 00000000..b70f1b46 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_SUNW.s @@ -0,0 +1,72 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + + .global XPTC_InvokeByIndex + .type XPTC_InvokeByIndex, #function +/* + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +*/ +XPTC_InvokeByIndex: + save %sp,-(64 + 32),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 32 + sll %i2,3,%l0 ! assume the worst case + ! paramCount * 2 * 4 bytes + cmp %l0, 0 ! are there any args? If not, + be .invoke ! no need to copy args to stack + + sub %sp,%l0,%sp ! create the additional stack space + add %sp,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 + +! +! load arguments from stack into the outgoing registers +! + ld [%sp + 72],%o1 + ld [%sp + 76],%o2 + ld [%sp + 80],%o3 + ld [%sp + 84],%o4 + ld [%sp + 88],%o5 + +! +! calculate the target address from the vtable +! +.invoke: + sll %i1,2,%l0 ! index *= 4 + add %l0,8,%l0 ! there are 2 extra entries in the vTable + ld [%i0],%l1 ! *that --> address of vtable + ld [%l0 + %l1],%l0 ! that->vtable[index * 4 + 8] --> address + + jmpl %l0,%o7 ! call the routine + mov %i0,%o0 ! move 'this' pointer to out register + + mov %o0,%i0 ! propagate return value + ret + restore + + .size XPTC_InvokeByIndex, .-XPTC_InvokeByIndex diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparcv9_solaris_SUNW.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparcv9_solaris_SUNW.s new file mode 100644 index 00000000..232ed6bd --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparcv9_solaris_SUNW.s @@ -0,0 +1,103 @@ +/* -*- Mode: asm; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 2001 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> + * Chris Seawood <cls@seawood.org> + */ + +/* + Platform specific code to invoke XPCOM methods on native objects + for sparcv9 Solaris. + + See the SPARC Compliance Definition (SCD) Chapter 3 + for more information about what is going on here, including + the use of BIAS (0x7ff). + The SCD is available from http://www.sparc.com/. +*/ + + .global XPTC_InvokeByIndex + .type XPTC_InvokeByIndex, #function + +/* + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +*/ +XPTC_InvokeByIndex: + save %sp,-(128 + 64),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 64 + sll %i2,4,%l0 ! assume the worst case + ! paramCount * 2 * 8 bytes + cmp %l0, 0 ! are there any args? If not, + be .invoke ! no need to copy args to stack + + sub %sp,%l0,%sp ! create the additional stack space + add %sp,0x7ff+136,%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 + +! +! load arguments from stack into the outgoing registers +! BIAS is 0x7ff (2047) +! + +! load the %o1..5 64bit (extended word) output registers registers + ldx [%sp + 0x7ff + 136],%o1 ! %i1 + ldx [%sp + 0x7ff + 144],%o2 ! %i2 + ldx [%sp + 0x7ff + 152],%o3 ! %i3 + ldx [%sp + 0x7ff + 160],%o4 ! %i4 + ldx [%sp + 0x7ff + 168],%o5 ! %i5 + +! load the even number double registers starting with %d2 + ldd [%sp + 0x7ff + 136],%d2 + ldd [%sp + 0x7ff + 144],%d4 + ldd [%sp + 0x7ff + 152],%d6 + ldd [%sp + 0x7ff + 160],%d8 + ldd [%sp + 0x7ff + 168],%d10 + ldd [%sp + 0x7ff + 176],%d12 + ldd [%sp + 0x7ff + 184],%d14 + ldd [%sp + 0x7ff + 192],%d16 + ldd [%sp + 0x7ff + 200],%d18 + ldd [%sp + 0x7ff + 208],%d20 + ldd [%sp + 0x7ff + 216],%d22 + ldd [%sp + 0x7ff + 224],%d24 + ldd [%sp + 0x7ff + 232],%d26 + ldd [%sp + 0x7ff + 240],%d28 + ldd [%sp + 0x7ff + 248],%d30 + +! +! calculate the target address from the vtable +! +.invoke: + sll %i1,3,%l0 ! index *= 8 + add %l0,16,%l0 ! there are 2 extra entries in the vTable (16bytes) + ldx [%i0],%l1 ! *that --> address of vtable + ldx [%l0 + %l1],%l0 ! that->vtable[index * 8 + 16] --> address + + jmpl %l0,%o7 ! call the routine + mov %i0,%o0 ! move 'this' pointer to out register + + mov %o0,%i0 ! propagate return value + ret + restore + + .size XPTC_InvokeByIndex, .-XPTC_InvokeByIndex diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp new file mode 100644 index 00000000..79b17ae3 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp @@ -0,0 +1,215 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#ifdef __GNUC__ /* Gnu compiler. */ + +#include "xptcprivate.h" +#include "xptc_platforms_unixish_x86.h" +#include "xptc_gcc_x86_unix.h" + +extern "C" { +#ifndef XP_WIN32 +static +#endif +void ATTRIBUTE_USED __attribute__ ((regparm(3))) +invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d) +{ + for(PRUint32 i = paramCount; i >0; i--, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + + switch(s->type) + { + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U64 : *((PRUint64*)d) = s->val.u64; d++; break; + case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; break; + default : *((void**)d) = s->val.p; break; + } + } +} +} // extern "C" + +// NOTE! See xptc_gcc_x86_unix.h for the reason why this function exists. +#if (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ == 0)) +PRUint32 +xptc_invoke_copy_to_stack_keeper (void) +{ + PRUint32 dummy1; + void ATTRIBUTE_USED __attribute__ ((regparm(3))) (*dummy2) + (PRUint32, nsXPTCVariant*, PRUint32*) = invoke_copy_to_stack; + +// dummy2 references invoke_copy_to_stack, now we have to "use" it + __asm__ __volatile__ ( + "" + : "=&a" (dummy1) + : "g" (dummy2) + ); + + return dummy1 & 0xF0F00000; +} +#endif + + +/* + XPTC_PUBLIC_API(nsresult) + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 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 + + NOTE NOTE NOTE: + As of 2002-04-29 this function references no global variables nor does + it call non-static functions so preserving and loading the PIC register + is unnecessary. Define MOZ_PRESERVE_PIC if this changes. See mozilla + bug 140412 for details. However, avoid this if you can. It's slower. +*/ +/* + * Hack for gcc for win32. Functions used externally must be + * explicitly dllexported. + * Bug 226609 + */ +#ifdef XP_WIN32 +extern "C" { + nsresult _XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + XPTC_PUBLIC_API(nsresult) + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) { + return _XPTC_InvokeByIndex(that, methodIndex, paramCount, params); + } +} +#endif + +__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" +#ifdef XP_WIN32 + ".globl " SYMBOL_UNDERSCORE "_XPTC_InvokeByIndex\n\t" + ".type " SYMBOL_UNDERSCORE "_XPTC_InvokeByIndex,@function\n" + SYMBOL_UNDERSCORE "_XPTC_InvokeByIndex:\n\t" +#else +#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP + ".globl " SYMBOL_UNDERSCORE "VBoxNsxpXPTC_InvokeByIndex\n\t" + ".type " SYMBOL_UNDERSCORE "VBoxNsxpXPTC_InvokeByIndex,@function\n" + SYMBOL_UNDERSCORE "VBoxNsxpXPTC_InvokeByIndex:\n\t" +#else + ".globl " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex\n\t" + ".type " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex,@function\n" + SYMBOL_UNDERSCORE "XPTC_InvokeByIndex:\n\t" +#endif +#endif + "pushl %ebp\n\t" + "movl %esp, %ebp\n\t" +#ifdef MOZ_PRESERVE_PIC + "pushl %ebx\n\t" + "call 0f\n\t" + ".subsection 1\n" + "0:\n\t" + "movl (%esp), %ebx\n\t" + "ret\n\t" + ".previous\n\t" + "addl $_GLOBAL_OFFSET_TABLE_, %ebx\n\t" +#endif + "movl 0x10(%ebp), %eax\n\t" + "leal 0(,%eax,8),%edx\n\t" + "movl %esp, %ecx\n\t" + "subl %edx, %ecx\n\t" +/* Since there may be 64-bit data, it occurs to me that aligning this + space might be a performance gain. However, I don't think the rest + of mozilla worries about such things. In any event, do it here. + "andl $0xfffffff8, %ecx\n\t" + */ + "movl %ecx, %esp\n\t" /* make stack space */ + "movl 0x14(%ebp), %edx\n\t" + "call " SYMBOL_UNDERSCORE "invoke_copy_to_stack\n\t" + "movl 0x08(%ebp), %ecx\n\t" /* 'that' */ +#ifdef CFRONT_STYLE_THIS_ADJUST + "movl (%ecx), %edx\n\t" + "movl 0x0c(%ebp), %eax\n\t" /* function index */ + "shll $3, %eax\n\t" /* *= 8 */ + "addl $8, %eax\n\t" /* += 8 skip first entry */ + "addl %eax, %edx\n\t" + "movswl (%edx), %eax\n\t" /* 'this' offset */ + "addl %eax, %ecx\n\t" + "pushl %ecx\n\t" + "addl $4, %edx\n\t" /* += 4, method pointer */ +#else /* THUNK_BASED_THIS_ADJUST */ + "pushl %ecx\n\t" + "movl (%ecx), %edx\n\t" + "movl 0x0c(%ebp), %eax\n\t" /* function index */ +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + "leal (%edx,%eax,4), %edx\n\t" +#else /* not G++ V3 ABI */ + "leal 8(%edx,%eax,4), %edx\n\t" +#endif /* G++ V3 ABI */ +#endif + "call *(%edx)\n\t" +#ifdef MOZ_PRESERVE_PIC + "movl -4(%ebp), %ebx\n\t" +#endif + "movl %ebp, %esp\n\t" + "popl %ebp\n\t" + "ret\n" +#ifdef XP_WIN32 + ".size " SYMBOL_UNDERSCORE "_XPTC_InvokeByIndex, . -" SYMBOL_UNDERSCORE "_XPTC_InvokeByIndex\n\t" +#else +#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP + ".size " SYMBOL_UNDERSCORE "VBoxNsxpXPTC_InvokeByIndex, . -" SYMBOL_UNDERSCORE "VBoxNsxpXPTC_InvokeByIndex\n\t" +#else + ".size " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex, . -" SYMBOL_UNDERSCORE "XPTC_InvokeByIndex\n\t" +#endif +#endif +); + +#else +#error "can't find a compiler to use" +#endif /* __GNUC__ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf32.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf32.cpp new file mode 100644 index 00000000..5a959317 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf32.cpp @@ -0,0 +1,164 @@ + +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "xptcprivate.h" + +#include <iostream.h> + +// "This code is for IA64 only" + + +/* invoke_copy_to_stack() will copy from variant array 's' to + * the stack argument area 'mloc', the integer register area 'iloc', and + * the float register area 'floc'. + * + */ +extern "C" void +invoke_copy_to_stack(uint64_t* mloc, uint64_t* iloc, uint64_t* floc, + const PRUint32 paramCount, nsXPTCVariant* s) +{ + uint64_t* dest = mloc; + PRUint32 len = paramCount; + nsXPTCVariant* source = s; + + PRUint32 indx; + PRUint32 endlen; + endlen = (len > 7) ? 7 : len; + /* handle the memory arguments */ + for (indx = 7; indx < len; ++indx) + { + if (source[indx].IsPtrData()) + { +#ifdef __LP64__ + /* 64 bit pointer mode */ + *((void**) dest) = source[indx].ptr; +#else + /* 32 bit pointer mode */ + uint32_t* adr = (uint32_t*) dest; + *(adr) = 0; + *(adr+1) = (uint32_t) source[indx].ptr; +#endif + } + else + switch (source[indx].type) + { + case nsXPTType::T_I8 : *(dest) = source[indx].val.i8; break; + case nsXPTType::T_I16 : *(dest) = source[indx].val.i16; break; + case nsXPTType::T_I32 : *(dest) = source[indx].val.i32; break; + case nsXPTType::T_I64 : *(dest) = source[indx].val.i64; break; + case nsXPTType::T_U8 : *(dest) = source[indx].val.u8; break; + case nsXPTType::T_U16 : *(dest) = source[indx].val.u16; break; + case nsXPTType::T_U32 : *(dest) = source[indx].val.u32; break; + case nsXPTType::T_U64 : *(dest) = source[indx].val.u64; break; + case nsXPTType::T_FLOAT : *(dest) = source[indx].val.u32; break; + case nsXPTType::T_DOUBLE: *(dest) = source[indx].val.u64; break; + case nsXPTType::T_BOOL : *(dest) = source[indx].val.b; break; + case nsXPTType::T_CHAR : *(dest) = source[indx].val.c; break; + case nsXPTType::T_WCHAR : *(dest) = source[indx].val.wc; break; + default: + // all the others are plain pointer types +#ifdef __LP64__ + /* 64 bit pointer mode */ + *((void**) dest) = source[indx].val.p; +#else + { + /* 32 bit pointer mode */ + uint32_t* adr = (uint32_t*) dest; + *(adr) = 0; + *(adr+1) = (uint32_t) source[indx].val.p; + } +#endif + } + ++dest; + } + /* process register arguments */ + dest = iloc; + for (indx = 0; indx < endlen; ++indx) + { + if (source[indx].IsPtrData()) + { +#ifdef __LP64__ + /* 64 bit pointer mode */ + *((void**) dest) = source[indx].ptr; +#else + /* 32 bit pointer mode */ + uint32_t* adr = (uint32_t*) dest; + *(adr) = 0; + *(adr+1) = (uint32_t) source[indx].ptr; +#endif + } + else + switch (source[indx].type) + { + case nsXPTType::T_I8 : *(dest) = source[indx].val.i8; break; + case nsXPTType::T_I16 : *(dest) = source[indx].val.i16; break; + case nsXPTType::T_I32 : *(dest) = source[indx].val.i32; break; + case nsXPTType::T_I64 : *(dest) = source[indx].val.i64; break; + case nsXPTType::T_U8 : *(dest) = source[indx].val.u8; break; + case nsXPTType::T_U16 : *(dest) = source[indx].val.u16; break; + case nsXPTType::T_U32 : *(dest) = source[indx].val.u32; break; + case nsXPTType::T_U64 : *(dest) = source[indx].val.u64; break; + case nsXPTType::T_FLOAT : + *((double*) (floc++)) = (double) source[indx].val.f; + break; + case nsXPTType::T_DOUBLE: + *((double*) (floc++)) = source[indx].val.d; + break; + case nsXPTType::T_BOOL : *(dest) = source[indx].val.b; break; + case nsXPTType::T_CHAR : *(dest) = source[indx].val.c; break; + case nsXPTType::T_WCHAR : *(dest) = source[indx].val.wc; break; + default: + // all the others are plain pointer types +#ifdef __LP64__ + /* 64 bit pointer mode */ + *((void**) dest) = source[indx].val.p; +#else + { + /* 32 bit pointer mode */ + uint32_t* adr = (uint32_t*) dest; + *(adr) = 0; + *(adr+1) = (uint32_t) source[indx].val.p; + } +#endif + } + ++dest; + } + +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf64.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf64.cpp new file mode 100644 index 00000000..356c2c7b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf64.cpp @@ -0,0 +1,133 @@ + +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "xptcprivate.h" + +#include <stdint.h> +#include <iostream.h> + +// "This code is for IA64 only" + + +/* invoke_copy_to_stack() will copy from variant array 's' to + * the stack argument area 'mloc', the integer register area 'iloc', and + * the float register area 'floc'. + * + */ +extern "C" void +invoke_copy_to_stack(uint64_t* mloc, uint64_t* iloc, uint64_t* floc, + const PRUint32 paramCount, nsXPTCVariant* s) +{ + uint64_t* dest = mloc; + PRUint32 len = paramCount; + nsXPTCVariant* source = s; + + PRUint32 indx; + PRUint32 endlen; + endlen = (len > 7) ? 7 : len; + /* handle the memory arguments */ + for (indx = 7; indx < len; ++indx) + { + if (source[indx].IsPtrData()) + { + /* 64 bit pointer mode */ + *((void**) dest) = source[indx].ptr; + } + else + switch (source[indx].type) + { + case nsXPTType::T_I8 : *(dest) = source[indx].val.i8; break; + case nsXPTType::T_I16 : *(dest) = source[indx].val.i16; break; + case nsXPTType::T_I32 : *(dest) = source[indx].val.i32; break; + case nsXPTType::T_I64 : *(dest) = source[indx].val.i64; break; + case nsXPTType::T_U8 : *(dest) = source[indx].val.u8; break; + case nsXPTType::T_U16 : *(dest) = source[indx].val.u16; break; + case nsXPTType::T_U32 : *(dest) = source[indx].val.u32; break; + case nsXPTType::T_U64 : *(dest) = source[indx].val.u64; break; + case nsXPTType::T_FLOAT : *(dest) = source[indx].val.u32; break; + case nsXPTType::T_DOUBLE: *(dest) = source[indx].val.u64; break; + case nsXPTType::T_BOOL : *(dest) = source[indx].val.b; break; + case nsXPTType::T_CHAR : *(dest) = source[indx].val.c; break; + case nsXPTType::T_WCHAR : *(dest) = source[indx].val.wc; break; + default: + // all the others are plain pointer types + /* 64 bit pointer mode */ + *((void**) dest) = source[indx].val.p; + } + ++dest; + } + /* process register arguments */ + dest = iloc; + for (indx = 0; indx < endlen; ++indx) + { + if (source[indx].IsPtrData()) + { + /* 64 bit pointer mode */ + *((void**) dest) = source[indx].ptr; + } + else + switch (source[indx].type) + { + case nsXPTType::T_I8 : *(dest) = source[indx].val.i8; break; + case nsXPTType::T_I16 : *(dest) = source[indx].val.i16; break; + case nsXPTType::T_I32 : *(dest) = source[indx].val.i32; break; + case nsXPTType::T_I64 : *(dest) = source[indx].val.i64; break; + case nsXPTType::T_U8 : *(dest) = source[indx].val.u8; break; + case nsXPTType::T_U16 : *(dest) = source[indx].val.u16; break; + case nsXPTType::T_U32 : *(dest) = source[indx].val.u32; break; + case nsXPTType::T_U64 : *(dest) = source[indx].val.u64; break; + case nsXPTType::T_FLOAT : + *((double*) (floc++)) = (double) source[indx].val.f; + break; + case nsXPTType::T_DOUBLE: + *((double*) (floc++)) = source[indx].val.d; + break; + case nsXPTType::T_BOOL : *(dest) = source[indx].val.b; break; + case nsXPTType::T_CHAR : *(dest) = source[indx].val.c; break; + case nsXPTType::T_WCHAR : *(dest) = source[indx].val.wc; break; + default: + // all the others are plain pointer types + /* 64 bit pointer mode */ + *((void**) dest) = source[indx].val.p; + } + ++dest; + } + +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_irix.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_irix.cpp new file mode 100644 index 00000000..67aa6144 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_irix.cpp @@ -0,0 +1,173 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +#if (_MIPS_SIM != _ABIN32) +#error "This code is for IRIX N32 only" +#endif + +extern "C" uint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + return(paramCount*2); +} + +extern "C" void +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, + nsXPTCVariant* s, PRUint64 *regs) +{ +#define N_ARG_REGS 7 /* 8 regs minus 1 for "this" ptr */ + + for (PRUint32 i = 0; i < paramCount; i++, s++) + { + if (s->IsPtrData()) { + if (i < N_ARG_REGS) + regs[i] = (PRUint64)s->ptr; + else + *d++ = (PRUint64)s->ptr; + continue; + } + switch (s->type) { + // + // signed types first + // + case nsXPTType::T_I8: + if (i < N_ARG_REGS) + ((PRInt64*)regs)[i] = s->val.i8; + else + *d++ = s->val.i8; + break; + case nsXPTType::T_I16: + if (i < N_ARG_REGS) + ((PRInt64*)regs)[i] = s->val.i16; + else + *d++ = s->val.i16; + break; + case nsXPTType::T_I32: + if (i < N_ARG_REGS) + ((PRInt64*)regs)[i] = s->val.i32; + else + *d++ = s->val.i32; + break; + case nsXPTType::T_I64: + if (i < N_ARG_REGS) + ((PRInt64*)regs)[i] = s->val.i64; + else + *d++ = s->val.i64; + break; + // + // unsigned types next + // + case nsXPTType::T_U8: + if (i < N_ARG_REGS) + regs[i] = s->val.u8; + else + *d++ = s->val.u8; + break; + case nsXPTType::T_U16: + if (i < N_ARG_REGS) + regs[i] = s->val.u16; + else + *d++ = s->val.u16; + break; + case nsXPTType::T_U32: + if (i < N_ARG_REGS) + regs[i] = s->val.u32; + else + *d++ = s->val.u32; + break; + case nsXPTType::T_U64: + if (i < N_ARG_REGS) + regs[i] = s->val.u64; + else + *d++ = s->val.u64; + break; + case nsXPTType::T_FLOAT: + if (i < N_ARG_REGS) + // Place a float in least significant bytes. + *(float*)(((char*)®s[i+1]) - sizeof(float)) = s->val.f; + else + *(float*)d++ = s->val.f; + break; + case nsXPTType::T_DOUBLE: + if (i < N_ARG_REGS) + *(double*)®s[i] = s->val.d; + else + *(double*)d++ = s->val.d; + break; + case nsXPTType::T_BOOL: + if (i < N_ARG_REGS) + regs[i] = s->val.b; + else + *d++ = s->val.b; + break; + case nsXPTType::T_CHAR: + if (i < N_ARG_REGS) + regs[i] = s->val.c; + else + *d++ = s->val.c; + break; + case nsXPTType::T_WCHAR: + if (i < N_ARG_REGS) + regs[i] = s->val.wc; + else + *d++ = s->val.wc; + break; + default: + // all the others are plain pointer types + if (i < N_ARG_REGS) + regs[i] = (PRUint64)s->val.p; + else + *d++ = (PRUint64)s->val.p; + break; + } + } +} + +extern "C" nsresult _XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +extern "C" +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + return _XPTC_InvokeByIndex(that, methodIndex, paramCount, params); +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_alpha.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_alpha.cpp new file mode 100644 index 00000000..7f7d84c3 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_alpha.cpp @@ -0,0 +1,181 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Glen Nakamura <glen@imodulo.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +/* Prototype specifies unmangled function name and disables unused warning */ +static void +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s) +__asm__("invoke_copy_to_stack") __attribute__((unused)); + +static void +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s) +{ + const PRUint8 NUM_ARG_REGS = 6-1; // -1 for "this" pointer + + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *d = (PRUint64)s->ptr; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : *d = (PRUint64)s->val.i8; break; + case nsXPTType::T_I16 : *d = (PRUint64)s->val.i16; break; + case nsXPTType::T_I32 : *d = (PRUint64)s->val.i32; break; + case nsXPTType::T_I64 : *d = (PRUint64)s->val.i64; break; + case nsXPTType::T_U8 : *d = (PRUint64)s->val.u8; break; + case nsXPTType::T_U16 : *d = (PRUint64)s->val.u16; break; + case nsXPTType::T_U32 : *d = (PRUint64)s->val.u32; break; + case nsXPTType::T_U64 : *d = (PRUint64)s->val.u64; break; + case nsXPTType::T_FLOAT : + if(i < NUM_ARG_REGS) + { + // convert floats to doubles if they are to be passed + // via registers so we can just deal with doubles later + union { PRUint64 u64; double d; } t; + t.d = (double)s->val.f; + *d = t.u64; + } + else + // otherwise copy to stack normally + *d = (PRUint64)s->val.u32; + break; + case nsXPTType::T_DOUBLE : *d = (PRUint64)s->val.u64; break; + case nsXPTType::T_BOOL : *d = (PRUint64)s->val.b; break; + case nsXPTType::T_CHAR : *d = (PRUint64)s->val.c; break; + case nsXPTType::T_WCHAR : *d = (PRUint64)s->val.wc; break; + default: + // all the others are plain pointer types + *d = (PRUint64)s->val.p; + break; + } + } +} + +/* + * XPTC_PUBLIC_API(nsresult) + * XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + * PRUint32 paramCount, nsXPTCVariant* params) + */ +__asm__( + "#### XPTC_InvokeByIndex ####\n" +".text\n\t" + ".align 5\n\t" + ".globl XPTC_InvokeByIndex\n\t" + ".ent XPTC_InvokeByIndex\n" +"XPTC_InvokeByIndex:\n\t" + ".frame $15,32,$26,0\n\t" + ".mask 0x4008000,-32\n\t" + "ldgp $29,0($27)\n" +"$XPTC_InvokeByIndex..ng:\n\t" + "subq $30,32,$30\n\t" + "stq $26,0($30)\n\t" + "stq $15,8($30)\n\t" + "bis $30,$30,$15\n\t" + ".prologue 1\n\t" + + /* + * Allocate enough stack space to hold the greater of 6 or "paramCount"+1 + * parameters. (+1 for "this" pointer) Room for at least 6 parameters + * is required for storage of those passed via registers. + */ + + "bis $31,5,$2\n\t" /* count = MAX(5, "paramCount") */ + "cmplt $2,$18,$1\n\t" + "cmovne $1,$18,$2\n\t" + "s8addq $2,16,$1\n\t" /* room for count+1 params (8 bytes each) */ + "bic $1,15,$1\n\t" /* stack space is rounded up to 0 % 16 */ + "subq $30,$1,$30\n\t" + + "stq $16,0($30)\n\t" /* save "that" (as "this" pointer) */ + "stq $17,16($15)\n\t" /* save "methodIndex" */ + + "addq $30,8,$16\n\t" /* pass stack pointer */ + "bis $18,$18,$17\n\t" /* pass "paramCount" */ + "bis $19,$19,$18\n\t" /* pass "params" */ + "bsr $26,$invoke_copy_to_stack..ng\n\t" /* call invoke_copy_to_stack */ + + /* + * Copy the first 6 parameters to registers and remove from stack frame. + * Both the integer and floating point registers are set for each parameter + * except the first which is the "this" pointer. (integer only) + * The floating point registers are all set as doubles since the + * invoke_copy_to_stack function should have converted the floats. + */ + "ldq $16,0($30)\n\t" /* integer registers */ + "ldq $17,8($30)\n\t" + "ldq $18,16($30)\n\t" + "ldq $19,24($30)\n\t" + "ldq $20,32($30)\n\t" + "ldq $21,40($30)\n\t" + "ldt $f17,8($30)\n\t" /* floating point registers */ + "ldt $f18,16($30)\n\t" + "ldt $f19,24($30)\n\t" + "ldt $f20,32($30)\n\t" + "ldt $f21,40($30)\n\t" + + "addq $30,48,$30\n\t" /* remove params from stack */ + + /* + * Call the virtual function with the constructed stack frame. + */ + "bis $16,$16,$1\n\t" /* load "this" */ + "ldq $2,16($15)\n\t" /* load "methodIndex" */ + "ldq $1,0($1)\n\t" /* load vtable */ +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + "s8addq $2,$31,$2\n\t" /* vtable index = "methodIndex" * 8 */ +#else /* not G++ V3 ABI */ + "s8addq $2,16,$2\n\t" /* vtable index = "methodIndex" * 8 + 16 */ +#endif /* G++ V3 ABI */ + "addq $1,$2,$1\n\t" + "ldq $27,0($1)\n\t" /* load address of function */ + "jsr $26,($27),0\n\t" /* call virtual function */ + "ldgp $29,0($26)\n\t" + + "bis $15,$15,$30\n\t" + "ldq $26,0($30)\n\t" + "ldq $15,8($30)\n\t" + "addq $30,32,$30\n\t" + "ret $31,($26),1\n\t" + ".end XPTC_InvokeByIndex" + ); diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_m68k.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_m68k.cpp new file mode 100644 index 00000000..363e45e0 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_m68k.cpp @@ -0,0 +1,170 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +// Remember that these 'words' are 32bit DWORDS + +extern "C" { + static PRUint32 + invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) + { + PRUint32 result = 0; + for(PRUint32 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; + } + } + return result; + } + + void + invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s) + { + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + switch(s->type) + { + // 8 and 16 bit types should be promoted to 32 bits when copying + // onto the stack. + case nsXPTType::T_I8 : *((PRUint32*)d) = s->val.i8; break; + case nsXPTType::T_I16 : *((PRUint32*)d) = s->val.i16; break; + case nsXPTType::T_I32 : *((PRInt32*) d) = s->val.i32; break; + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U8 : *((PRUint32*)d) = s->val.u8; break; + case nsXPTType::T_U16 : *((PRUint32*)d) = s->val.u16; break; + case nsXPTType::T_U32 : *((PRUint32*)d) = s->val.u32; break; + case nsXPTType::T_U64 : *((PRUint64*)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 : *((PRBool*) d) = s->val.b; break; + case nsXPTType::T_CHAR : *((PRUint32*)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; + } + } + } +} + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + PRUint32 result, n; + + n = invoke_count_words(paramCount, params) * 4; + + __asm__ __volatile__( + "subl %5, %/sp\n\t" /* make room for params */ + "movl %/sp, %/a0\n\t" + "movl %4, %/sp@-\n\t" + "movl %3, %/sp@-\n\t" + "movl %/a0, %/sp@-\n\t" + "jbsr invoke_copy_to_stack\n\t" /* copy params */ + "addl #12, %/sp\n\t" + "movl %1, %/a0\n\t" + "movl %/a0, %/sp@-\n\t" + "movl %/a0@, %/a0\n\t" + "movl %2, %/d0\n\t" /* function index */ +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + "movl %/a0@(%/d0:l:4), %/a0\n\t" +#else /* not V3 */ + "movl %/a0@(8,%/d0:l:4), %/a0\n\t" +#endif + "jbsr %/a0@\n\t" /* safe to not cleanup sp */ + "movl %/d0, %0\n\t" + "addql #4, %/sp\n\t" + "addl %5, %/sp" + : "=g" (result) /* %0 */ + : "g" (that), /* %1 */ + "g" (methodIndex), /* %2 */ + "g" (paramCount), /* %3 */ + "g" (params), /* %4 */ + "g" (n) /* %5 */ + : "a0", "a1", "d0", "d1", "memory" + ); + + return result; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390.cpp new file mode 100644 index 00000000..5da035ca --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390.cpp @@ -0,0 +1,254 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + + +static PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 overflow = 0, gpr = 1 /*this*/, fpr = 0; + for(PRUint32 i = 0; i < paramCount; i++, s++) + { + if(s->IsPtrData()) + { + if (gpr < 5) gpr++; else overflow++; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : + case nsXPTType::T_I16 : + case nsXPTType::T_I32 : + if (gpr < 5) gpr++; else overflow++; + break; + case nsXPTType::T_I64 : + if (gpr < 4) gpr+=2; else gpr=5, overflow+=2; + break; + case nsXPTType::T_U8 : + case nsXPTType::T_U16 : + case nsXPTType::T_U32 : + if (gpr < 5) gpr++; else overflow++; + break; + case nsXPTType::T_U64 : + if (gpr < 4) gpr+=2; else gpr=5, overflow+=2; + break; + case nsXPTType::T_FLOAT : + if (fpr < 2) fpr++; else overflow++; + break; + case nsXPTType::T_DOUBLE : + if (fpr < 2) fpr++; else overflow+=2; + break; + case nsXPTType::T_BOOL : + case nsXPTType::T_CHAR : + case nsXPTType::T_WCHAR : + if (gpr < 5) gpr++; else overflow++; + break; + default: + // all the others are plain pointer types + if (gpr < 5) gpr++; else overflow++; + break; + } + } + /* Round up number of overflow words to ensure stack + stays aligned to 8 bytes. */ + return (overflow + 1) & ~1; +} + +static void +invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d_ov, PRUint32 overflow) +{ + PRUint32 *d_gpr = d_ov + overflow; + PRUint64 *d_fpr = (PRUint64 *)(d_gpr + 4); + PRUint32 gpr = 1 /*this*/, fpr = 0; + + for(PRUint32 i = 0; i < paramCount; i++, s++) + { + if(s->IsPtrData()) + { + if (gpr < 5) + *((void**)d_gpr) = s->ptr, d_gpr++, gpr++; + else + *((void**)d_ov ) = s->ptr, d_ov++; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : + if (gpr < 5) + *((PRInt32*) d_gpr) = s->val.i8, d_gpr++, gpr++; + else + *((PRInt32*) d_ov ) = s->val.i8, d_ov++; + break; + case nsXPTType::T_I16 : + if (gpr < 5) + *((PRInt32*) d_gpr) = s->val.i16, d_gpr++, gpr++; + else + *((PRInt32*) d_ov ) = s->val.i16, d_ov++; + break; + case nsXPTType::T_I32 : + if (gpr < 5) + *((PRInt32*) d_gpr) = s->val.i32, d_gpr++, gpr++; + else + *((PRInt32*) d_ov ) = s->val.i32, d_ov++; + break; + case nsXPTType::T_I64 : + if (gpr < 4) + *((PRInt64*) d_gpr) = s->val.i64, d_gpr+=2, gpr+=2; + else + *((PRInt64*) d_ov ) = s->val.i64, d_ov+=2, gpr=5; + break; + case nsXPTType::T_U8 : + if (gpr < 5) + *((PRUint32*) d_gpr) = s->val.u8, d_gpr++, gpr++; + else + *((PRUint32*) d_ov ) = s->val.u8, d_ov++; + break; + case nsXPTType::T_U16 : + if (gpr < 5) + *((PRUint32*)d_gpr) = s->val.u16, d_gpr++, gpr++; + else + *((PRUint32*)d_ov ) = s->val.u16, d_ov++; + break; + case nsXPTType::T_U32 : + if (gpr < 5) + *((PRUint32*)d_gpr) = s->val.u32, d_gpr++, gpr++; + else + *((PRUint32*)d_ov ) = s->val.u32, d_ov++; + break; + case nsXPTType::T_U64 : + if (gpr < 4) + *((PRUint64*)d_gpr) = s->val.u64, d_gpr+=2, gpr+=2; + else + *((PRUint64*)d_ov ) = s->val.u64, d_ov+=2, gpr=5; + break; + case nsXPTType::T_FLOAT : + if (fpr < 2) + *((float*) d_fpr) = s->val.f, d_fpr++, fpr++; + else + *((float*) d_ov ) = s->val.f, d_ov++; + break; + case nsXPTType::T_DOUBLE : + if (fpr < 2) + *((double*) d_fpr) = s->val.d, d_fpr++, fpr++; + else + *((double*) d_ov ) = s->val.d, d_ov+=2; + break; + case nsXPTType::T_BOOL : + if (gpr < 5) + *((PRUint32*)d_gpr) = s->val.b, d_gpr++, gpr++; + else + *((PRUint32*)d_ov ) = s->val.b, d_ov++; + break; + case nsXPTType::T_CHAR : + if (gpr < 5) + *((PRUint32*)d_gpr) = s->val.c, d_gpr++, gpr++; + else + *((PRUint32*)d_ov ) = s->val.c, d_ov++; + break; + case nsXPTType::T_WCHAR : + if (gpr < 5) + *((PRUint32*)d_gpr) = s->val.wc, d_gpr++, gpr++; + else + *((PRUint32*)d_ov ) = s->val.wc, d_ov++; + break; + default: + // all the others are plain pointer types + if (gpr < 5) + *((void**) d_gpr) = s->val.p, d_gpr++, gpr++; + else + *((void**) d_ov ) = s->val.p, d_ov++; + break; + } + } +} + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + PRUint32 *vtable = *(PRUint32 **)that; +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + PRUint32 method = vtable[methodIndex]; +#else /* not G++ V3 ABI */ + PRUint32 method = vtable[methodIndex + 2]; +#endif /* G++ V3 ABI */ + PRUint32 overflow = invoke_count_words (paramCount, params); + PRUint32 result; + + __asm__ __volatile__ + ( + "lr 7,15\n\t" + "ahi 7,-32\n\t" + + "lr 3,%3\n\t" + "sll 3,2\n\t" + "lcr 3,3\n\t" + "l 2,0(15)\n\t" + "la 15,0(3,7)\n\t" + "st 2,0(15)\n\t" + + "lr 2,%1\n\t" + "lr 3,%2\n\t" + "la 4,96(15)\n\t" + "lr 5,%3\n\t" + "basr 14,%4\n\t" + + "lr 2,%5\n\t" + "ld 0,112(7)\n\t" + "ld 2,120(7)\n\t" + "lm 3,6,96(7)\n\t" + "basr 14,%6\n\t" + + "la 15,32(7)\n\t" + + "lr %0,2\n\t" + : "=r" (result) + : "r" (paramCount), + "r" (params), + "r" (overflow), + "a" (invoke_copy_to_stack), + "a" (that), + "a" (method) + : "2", "3", "4", "5", "6", "7", "memory" + ); + + return result; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390x.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390x.cpp new file mode 100644 index 00000000..5a4268b6 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390x.cpp @@ -0,0 +1,250 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + + +static PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 overflow = 0, gpr = 1 /*this*/, fpr = 0; + for(PRUint32 i = 0; i < paramCount; i++, s++) + { + if(s->IsPtrData()) + { + if (gpr < 5) gpr++; else overflow++; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : + case nsXPTType::T_I16 : + case nsXPTType::T_I32 : + case nsXPTType::T_I64 : + if (gpr < 5) gpr++; else overflow++; + break; + case nsXPTType::T_U8 : + case nsXPTType::T_U16 : + case nsXPTType::T_U32 : + case nsXPTType::T_U64 : + if (gpr < 5) gpr++; else overflow++; + break; + case nsXPTType::T_FLOAT : + case nsXPTType::T_DOUBLE : + if (fpr < 4) fpr++; else overflow++; + break; + case nsXPTType::T_BOOL : + case nsXPTType::T_CHAR : + case nsXPTType::T_WCHAR : + if (gpr < 5) gpr++; else overflow++; + break; + default: + // all the others are plain pointer types + if (gpr < 5) gpr++; else overflow++; + break; + } + } + /* Round up number of overflow words to ensure stack + stays aligned to 8 bytes. */ + return (overflow + 1) & ~1; +} + +static void +invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint64* d_ov, PRUint32 overflow) +{ + PRUint64 *d_gpr = d_ov + overflow; + PRUint64 *d_fpr = (PRUint64 *)(d_gpr + 4); + PRUint32 gpr = 1 /*this*/, fpr = 0; + + for(PRUint32 i = 0; i < paramCount; i++, s++) + { + if(s->IsPtrData()) + { + if (gpr < 5) + *((void**)d_gpr) = s->ptr, d_gpr++, gpr++; + else + *((void**)d_ov ) = s->ptr, d_ov++; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : + if (gpr < 5) + *((PRInt64*) d_gpr) = s->val.i8, d_gpr++, gpr++; + else + *((PRInt64*) d_ov ) = s->val.i8, d_ov++; + break; + case nsXPTType::T_I16 : + if (gpr < 5) + *((PRInt64*) d_gpr) = s->val.i16, d_gpr++, gpr++; + else + *((PRInt64*) d_ov ) = s->val.i16, d_ov++; + break; + case nsXPTType::T_I32 : + if (gpr < 5) + *((PRInt64*) d_gpr) = s->val.i32, d_gpr++, gpr++; + else + *((PRInt64*) d_ov ) = s->val.i32, d_ov++; + break; + case nsXPTType::T_I64 : + if (gpr < 5) + *((PRInt64*) d_gpr) = s->val.i64, d_gpr++, gpr++; + else + *((PRInt64*) d_ov ) = s->val.i64, d_ov++; + break; + case nsXPTType::T_U8 : + if (gpr < 5) + *((PRUint64*) d_gpr) = s->val.u8, d_gpr++, gpr++; + else + *((PRUint64*) d_ov ) = s->val.u8, d_ov++; + break; + case nsXPTType::T_U16 : + if (gpr < 5) + *((PRUint64*)d_gpr) = s->val.u16, d_gpr++, gpr++; + else + *((PRUint64*)d_ov ) = s->val.u16, d_ov++; + break; + case nsXPTType::T_U32 : + if (gpr < 5) + *((PRUint64*)d_gpr) = s->val.u32, d_gpr++, gpr++; + else + *((PRUint64*)d_ov ) = s->val.u32, d_ov++; + break; + case nsXPTType::T_U64 : + if (gpr < 5) + *((PRUint64*)d_gpr) = s->val.u64, d_gpr++, gpr++; + else + *((PRUint64*)d_ov ) = s->val.u64, d_ov++; + break; + case nsXPTType::T_FLOAT : + if (fpr < 4) + *((float*) d_fpr) = s->val.f, d_fpr++, fpr++; + else + *(((float*) d_ov )+1) = s->val.f, d_ov++; + break; + case nsXPTType::T_DOUBLE : + if (fpr < 4) + *((double*) d_fpr) = s->val.d, d_fpr++, fpr++; + else + *((double*) d_ov ) = s->val.d, d_ov++; + break; + case nsXPTType::T_BOOL : + if (gpr < 5) + *((PRUint64*)d_gpr) = s->val.b, d_gpr++, gpr++; + else + *((PRUint64*)d_ov ) = s->val.b, d_ov++; + break; + case nsXPTType::T_CHAR : + if (gpr < 5) + *((PRUint64*)d_gpr) = s->val.c, d_gpr++, gpr++; + else + *((PRUint64*)d_ov ) = s->val.c, d_ov++; + break; + case nsXPTType::T_WCHAR : + if (gpr < 5) + *((PRUint64*)d_gpr) = s->val.wc, d_gpr++, gpr++; + else + *((PRUint64*)d_ov ) = s->val.wc, d_ov++; + break; + default: + // all the others are plain pointer types + if (gpr < 5) + *((void**) d_gpr) = s->val.p, d_gpr++, gpr++; + else + *((void**) d_ov ) = s->val.p, d_ov++; + break; + } + } +} + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + PRUint64 *vtable = *(PRUint64 **)that; +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + PRUint64 method = vtable[methodIndex]; +#else /* not G++ V3 ABI */ + PRUint64 method = vtable[methodIndex + 2]; +#endif /* G++ V3 ABI */ + PRUint64 overflow = invoke_count_words (paramCount, params); + PRUint64 result; + + __asm__ __volatile__ + ( + "lgr 7,15\n\t" + "aghi 7,-64\n\t" + + "lgr 3,%3\n\t" + "sllg 3,3,3\n\t" + "lcgr 3,3\n\t" + "lg 2,0(15)\n\t" + "la 15,0(3,7)\n\t" + "stg 2,0(15)\n\t" + + "lgr 2,%1\n\t" + "lgr 3,%2\n\t" + "la 4,160(15)\n\t" + "lgr 5,%3\n\t" + "basr 14,%4\n\t" + + "lgr 2,%5\n\t" + "ld 0,192(7)\n\t" + "ld 2,200(7)\n\t" + "ld 4,208(7)\n\t" + "ld 6,216(7)\n\t" + "lmg 3,6,160(7)\n\t" + "basr 14,%6\n\t" + + "la 15,64(7)\n\t" + + "lgr %0,2\n\t" + : "=r" (result) + : "r" ((PRUint64)paramCount), + "r" (params), + "r" (overflow), + "a" (invoke_copy_to_stack), + "a" (that), + "a" (method) + : "2", "3", "4", "5", "6", "7", "memory" + ); + + return result; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_mips.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_mips.cpp new file mode 100644 index 00000000..a73e4327 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_mips.cpp @@ -0,0 +1,122 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * Version: MPL 1.1 + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp, Inc. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> + * Brendan Eich <brendan@mozilla.org> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* This code is for MIPS using the O32 ABI. */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + + +extern "C" uint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + // Count a word for a0 even though it's never stored or loaded + // We do this only for alignment of register pairs. + PRUint32 result = 1; + for (PRUint32 i = 0; i < paramCount; i++, s++) + { + result++; + + if (s->IsPtrData()) + continue; + + switch(s->type) + { + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + case nsXPTType::T_DOUBLE : + if (result & 1) + result++; + result++; + break; + } + } + return (result + 1) & ~(PRUint32)1; +} + +extern "C" void +invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, + nsXPTCVariant* s) +{ + // Skip the unused a0 slot, which we keep only for register pair alignment. + d++; + + for (PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if (s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + + *((void**)d) = s->val.p; + + switch(s->type) + { + case nsXPTType::T_I64 : + if ((PRWord)d & 4) d++; + *((PRInt64*) d) = s->val.i64; d++; + break; + case nsXPTType::T_U64 : + if ((PRWord)d & 4) d++; + *((PRUint64*) d) = s->val.u64; d++; + break; + case nsXPTType::T_DOUBLE : + if ((PRWord)d & 4) d++; + *((double*) d) = s->val.d; d++; + break; + } + } +} + +extern "C" nsresult _XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, + nsXPTCVariant* params); + +extern "C" +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + return _XPTC_InvokeByIndex(that, methodIndex, paramCount, params); +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_netbsd_m68k.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_netbsd_m68k.cpp new file mode 100644 index 00000000..65bf8f0c --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_netbsd_m68k.cpp @@ -0,0 +1,175 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +// Remember that these 'words' are 32bit DWORDS + +#if !defined(__NetBSD__) || !defined(__m68k__) +#error This code is for NetBSD/m68k only +#endif + +extern "C" { + static PRUint32 + invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) + { + PRUint32 result = 0; + for(PRUint32 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; + } + } + return result; + } + + static void + invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s) + { + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + switch(s->type) + { + // 8 and 16 bit types should be promoted to 32 bits when copying + // onto the stack. + case nsXPTType::T_I8 : *((PRUint32*)d) = s->val.i8; break; + case nsXPTType::T_I16 : *((PRUint32*)d) = s->val.i16; break; + case nsXPTType::T_I32 : *((PRInt32*) d) = s->val.i32; break; + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U8 : *((PRUint32*)d) = s->val.u8; break; + case nsXPTType::T_U16 : *((PRUint32*)d) = s->val.u16; break; + case nsXPTType::T_U32 : *((PRUint32*)d) = s->val.u32; break; + case nsXPTType::T_U64 : *((PRUint64*)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 : *((PRBool*) d) = s->val.b; break; + case nsXPTType::T_CHAR : *((PRUint32*)d) = s->val.c; break; + // wchar_t is an int (32 bits) on NetBSD + 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; + } + } + } +} + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + PRUint32 result; + + __asm__ __volatile__( + "movl %4, sp@-\n\t" + "movl %3, sp@-\n\t" + "jbsr _invoke_count_words\n\t" /* count words */ + "addql #8, sp\n\t" + "lsll #2, d0\n\t" /* *= 4 */ + "movl sp, a2\n\t" /* save original sp */ + "subl d0, sp\n\t" /* make room for params */ + "movl sp, a0\n\t" + "movl %4, sp@-\n\t" + "movl %3, sp@-\n\t" + "movl a0, sp@-\n\t" + "jbsr _invoke_copy_to_stack\n\t" /* copy params */ + "addl #12, sp\n\t" + "movl %1, a0\n\t" + "movl a0@, a1\n\t" + "movl %2, d0\n\t" /* function index */ + "movl a0, d1\n\t" + "movw a1@(8,d0:l:8), a0\n\t" + "addl a0, d1\n\t" + "movl a1@(12,d0:l:8), a1\n\t" + "movl d1, sp@-\n\t" + "jbsr a1@\n\t" + "movl a2, sp\n\t" /* restore original sp */ + "movl d0, %0\n\t" + : "=g" (result) /* %0 */ + : "g" (that), /* %1 */ + "g" (methodIndex), /* %2 */ + "g" (paramCount), /* %3 */ + "g" (params) /* %4 */ + : "a0", "a1", "a2", "d0", "d1", "memory" + ); + + return result; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_openvms_alpha.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_openvms_alpha.cpp new file mode 100644 index 00000000..ae22a48c --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_openvms_alpha.cpp @@ -0,0 +1,107 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +extern "C" { + +/* This is in the ASM file */ +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + + +void +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s) +{ + const PRUint8 NUM_ARG_REGS = 6-1; // -1 for "this" pointer + + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *d = (PRUint64)s->ptr; + continue; + } + switch(s->type) + { + /* + ** The line for T_U32 may look wrong (we use signed value for an + ** unsigned data type), but it is right. Why? The Alpha calling + ** standard is defined to sign extend all 32-bit values, regardless + ** of whether they are int, unsigned int, or 32-bit pointer. The + ** caller must "sign-extend" it by replicating bit 31 in bits 32 + ** thru 63 (yes, even for unsigned). This is the format that results + ** naturally from the LDL instruction, the ADDL instruction, etc. + */ + case nsXPTType::T_I8 : *d = (PRUint64)s->val.i8; break; + case nsXPTType::T_I16 : *d = (PRUint64)s->val.i16; break; + case nsXPTType::T_I32 : *d = (PRUint64)s->val.i32; break; + case nsXPTType::T_I64 : *d = (PRUint64)s->val.i64; break; + case nsXPTType::T_U8 : *d = (PRUint64)s->val.u8; break; + case nsXPTType::T_U16 : *d = (PRUint64)s->val.u16; break; + case nsXPTType::T_U32 : *d = (PRUint64)s->val.i32; break; + case nsXPTType::T_U64 : *d = (PRUint64)s->val.u64; break; + case nsXPTType::T_FLOAT : + if(i < NUM_ARG_REGS) + { + // convert floats to doubles if they are to be passed + // via registers so we can just deal with doubles later + union { PRUint64 u64; double d; } t; + t.d = (double)s->val.f; + *d = t.u64; + } + else + // otherwise copy to stack normally + *d = (PRUint64)s->val.u32; + break; + case nsXPTType::T_DOUBLE : *d = (PRUint64)s->val.u64; break; + case nsXPTType::T_BOOL : *d = (PRUint64)s->val.b; break; + case nsXPTType::T_CHAR : *d = (PRUint64)s->val.c; break; + case nsXPTType::T_WCHAR : *d = (PRUint64)s->val.wc; break; + default: + // all the others are plain pointer types + *d = (PRUint64)s->val.p; + break; + } + } +} + +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_osf1_alpha.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_osf1_alpha.cpp new file mode 100644 index 00000000..13c3b23d --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_osf1_alpha.cpp @@ -0,0 +1,93 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +/* contributed by Steve Streeter <Stephen.Streeter@Compaq.com> */ + +#include "xptcprivate.h" + +/* Prototype specifies unmangled function name */ +extern "C" void +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s); + +extern "C" void +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s) +{ + const PRUint8 NUM_ARG_REGS = 6-1; // -1 for "this" pointer + + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *d = (PRUint64)s->ptr; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : *d = (PRUint64)s->val.i8; break; + case nsXPTType::T_I16 : *d = (PRUint64)s->val.i16; break; + case nsXPTType::T_I32 : *d = (PRUint64)s->val.i32; break; + case nsXPTType::T_I64 : *d = (PRUint64)s->val.i64; break; + case nsXPTType::T_U8 : *d = (PRUint64)s->val.u8; break; + case nsXPTType::T_U16 : *d = (PRUint64)s->val.u16; break; + case nsXPTType::T_U32 : *d = (PRUint64)s->val.u32; break; + case nsXPTType::T_U64 : *d = (PRUint64)s->val.u64; break; + case nsXPTType::T_FLOAT : + if(i < NUM_ARG_REGS) + { + // convert floats to doubles if they are to be passed + // via registers so we can just deal with doubles later + union { PRUint64 u64; double d; } t; + t.d = (double)s->val.f; + *d = t.u64; + } + else + // otherwise copy to stack normally + *d = (PRUint64)s->val.u32; + break; + case nsXPTType::T_DOUBLE : *d = (PRUint64)s->val.u64; break; + case nsXPTType::T_BOOL : *d = (PRUint64)s->val.b; break; + case nsXPTType::T_CHAR : *d = (PRUint64)s->val.c; break; + case nsXPTType::T_WCHAR : *d = (PRUint64)s->val.wc; break; + default: + // all the others are plain pointer types + *d = (PRUint64)s->val.p; + break; + } + } +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_pa32.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_pa32.cpp new file mode 100644 index 00000000..c6208a50 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_pa32.cpp @@ -0,0 +1,181 @@ + +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "xptcprivate.h" + +#if _HPUX +#error "This code is for HP-PA RISC 32 bit mode only" +#endif + +#include <alloca.h> + +typedef unsigned nsXPCVariant; + +extern "C" PRInt32 +invoke_count_bytes(nsISupports* that, const PRUint32 methodIndex, + const PRUint32 paramCount, const nsXPTCVariant* s) +{ + PRInt32 result = 4; /* variant records do not include self pointer */ + + /* counts the number of bytes required by the argument stack, + 64 bit integer, and double requires 8 bytes. All else requires + 4 bytes. + */ + + { + PRUint32 indx; + for (indx = paramCount; indx > 0; --indx, ++s) + { + if (! s->IsPtrData()) + { + if (s->type == nsXPTType::T_I64 || s->type == nsXPTType::T_U64 || + s->type == nsXPTType::T_DOUBLE) + { + /* 64 bit integer and double aligned on 8 byte boundaries */ + result += (result & 4) + 8; + continue; + } + } + result += 4; /* all other cases use 4 bytes */ + } + } + result -= 72; /* existing stack buffer is 72 bytes */ + if (result < 0) + return 0; + { + /* round up to 64 bytes boundary */ + PRInt32 remainder = result & 63; + return (remainder == 0) ? result : (result + 64 - remainder); + } +} + +extern "C" PRUint32 +invoke_copy_to_stack(PRUint32* d, + const PRUint32 paramCount, nsXPTCVariant* s) +{ + + typedef struct + { + PRUint32 hi; + PRUint32 lo; + } DU; + + PRUint32* dest = d; + nsXPTCVariant* source = s; + /* we clobber param vars by copying stuff on stack, have to use local var */ + + PRUint32 floatflags = 0; + /* flag indicating which floating point registers to load */ + + PRUint32 regwords = 1; /* register 26 is reserved for ptr to 'that' */ + PRUint32 indx; + + for (indx = paramCount; indx > 0; --indx, --dest, ++source) + { + if (source->IsPtrData()) + { + *((void**) dest) = source->ptr; + ++regwords; + continue; + } + switch (source->type) + { + case nsXPTType::T_I8 : *((PRInt32*) dest) = source->val.i8; break; + case nsXPTType::T_I16 : *((PRInt32*) dest) = source->val.i16; break; + case nsXPTType::T_I32 : *((PRInt32*) dest) = source->val.i32; break; + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + if (regwords & 1) + { + /* align on double word boundary */ + --dest; + ++regwords; + } + *((uint32*) dest) = ((DU *) source)->lo; + *((uint32*) --dest) = ((DU *) source)->hi; + /* big endian - hi word in low addr */ + regwords += 2; + continue; + case nsXPTType::T_DOUBLE : + if (regwords & 1) + { + /* align on double word boundary */ + --dest; + ++regwords; + } + switch (regwords) /* load double precision float register */ + { + case 2: + floatflags |= 1; + } + *((uint32*) dest) = ((DU *) source)->lo; + *((uint32*) --dest) = ((DU *) source)->hi; + /* big endian - hi word in low addr */ + regwords += 2; + continue; + case nsXPTType::T_FLOAT : + switch (regwords) /* load single precision float register */ + { + case 1: + floatflags |= 2; + break; + case 2: + floatflags |= 4; + break; + case 3: + floatflags |= 8; + } + *((float*) dest) = source->val.f; + break; + case nsXPTType::T_U8 : *((PRUint32*) (dest)) = source->val.u8; break; + case nsXPTType::T_U16 : *((PRUint32*) (dest)) = source->val.u16; break; + case nsXPTType::T_U32 : *((PRUint32*) (dest)) = source->val.u32; break; + case nsXPTType::T_BOOL : *((PRBool*) (dest)) = source->val.b; break; + case nsXPTType::T_CHAR : *((PRUint32*) (dest)) = source->val.c; break; + case nsXPTType::T_WCHAR : *((PRInt32*) (dest)) = source->val.wc; break; + + default: + // all the others are plain pointer types + *((void**) dest) = source->val.p; + } + ++regwords; + } + return floatflags; +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix.cpp new file mode 100644 index 00000000..d353063c --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix.cpp @@ -0,0 +1,106 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +#ifndef AIX +#error "This code is for PowerPC only" +#endif + +extern "C" void +invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s, double *fprData) +{ +/* + 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. +*/ + PRUint32 *l_d = d; + nsXPTCVariant *l_s = s; + PRUint32 l_paramCount = paramCount, fpCount = 0; + double *l_fprData = fprData; + + typedef struct { + uint32 hi; + uint32 lo; + } DU; // have to move 64 bit entities as 32 bit halves since + // stack slots are not guaranteed 16 byte aligned + + for(uint32 i = 0; i < l_paramCount; i++, l_d++, l_s++) + { + if(l_s->IsPtrData()) + { + *((void**)l_d) = l_s->ptr; + continue; + } + switch(l_s->type) + { + case nsXPTType::T_I8 : *((int32*) l_d) = l_s->val.i8; break; + case nsXPTType::T_I16 : *((int32*) l_d) = l_s->val.i16; break; + case nsXPTType::T_I32 : *((int32*) l_d) = l_s->val.i32; break; + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + *((uint32*) l_d++) = ((DU *)l_s)->hi; + *((uint32*) l_d) = ((DU *)l_s)->lo; + break; + case nsXPTType::T_DOUBLE : + *((uint32*) l_d++) = ((DU *)l_s)->hi; + *((uint32*) l_d) = ((DU *)l_s)->lo; + if(fpCount < 13) + l_fprData[fpCount++] = l_s->val.d; + break; + case nsXPTType::T_U8 : *((uint32*) l_d) = l_s->val.u8; break; + case nsXPTType::T_U16 : *((uint32*) l_d) = l_s->val.u16; break; + case nsXPTType::T_U32 : *((uint32*) l_d) = l_s->val.u32; break; + case nsXPTType::T_FLOAT : + *((float*) l_d) = l_s->val.f; + if(fpCount < 13) + l_fprData[fpCount++] = l_s->val.f; + break; + case nsXPTType::T_BOOL : *((PRBool*) l_d) = l_s->val.b; break; + case nsXPTType::T_CHAR : *((uint32*) l_d) = l_s->val.c; break; + case nsXPTType::T_WCHAR : *((int32*) l_d) = l_s->val.wc; break; + default: + // all the others are plain pointer types + *((void**)l_d) = l_s->val.p; + break; + } + } +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix64.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix64.cpp new file mode 100644 index 00000000..a42611b8 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix64.cpp @@ -0,0 +1,95 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/LGPL 2.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by IBM are + * Copyright (C) 2002, International Business Machines Corporation. + * All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the LGPL or the GPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +#ifdef _AIX + +extern "C" void +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s, double *fprData) +{ +/* + 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. +*/ + PRUint64 *l_d = d; + nsXPTCVariant *l_s = s; + PRUint32 l_paramCount = paramCount, fpCount = 0; + double *l_fprData = fprData; + + for(PRUint32 i = 0; i < l_paramCount; i++, l_d++, l_s++) + { + if(l_s->IsPtrData()) + { + *l_d = (PRUint64)l_s->ptr; + continue; + } + switch(l_s->type) + { + case nsXPTType::T_I8: *l_d = (PRUint64)l_s->val.i8; break; + case nsXPTType::T_I16: *l_d = (PRUint64)l_s->val.i16; break; + case nsXPTType::T_I32: *l_d = (PRUint64)l_s->val.i32; break; + case nsXPTType::T_I64: *l_d = (PRUint64)l_s->val.i64; break; + case nsXPTType::T_U8: *l_d = (PRUint64)l_s->val.u8; break; + case nsXPTType::T_U16: *l_d = (PRUint64)l_s->val.u16; break; + case nsXPTType::T_U32: *l_d = (PRUint64)l_s->val.u32; break; + case nsXPTType::T_U64: *l_d = (PRUint64)l_s->val.u64; break; + case nsXPTType::T_BOOL: *l_d = (PRUint64)l_s->val.b; break; + case nsXPTType::T_CHAR: *l_d = (PRUint64)l_s->val.c; break; + case nsXPTType::T_WCHAR: *l_d = (PRUint64)l_s->val.wc; break; + + case nsXPTType::T_DOUBLE: + *((double*)l_d) = l_s->val.d; + if(fpCount < 13) + l_fprData[fpCount++] = l_s->val.d; + break; + case nsXPTType::T_FLOAT: + *((float*)l_d) = l_s->val.f; + if(fpCount < 13) + l_fprData[fpCount++] = l_s->val.f; + break; + default: + // all the others are plain pointer types + *l_d = (PRUint64)l_s->val.p; + break; + } + } +} +#endif + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_linux.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_linux.cpp new file mode 100644 index 00000000..7303045a --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_linux.cpp @@ -0,0 +1,141 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Franz.Sirl-kernel@lauterbach.com (Franz Sirl) + * beard@netscape.com (Patrick Beard) + * waterson@netscape.com (Chris Waterson) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Platform specific code to invoke XPCOM methods on native objects + +// The purpose of XPTC_InvokeByIndex() is to map a platform +// indepenpent call to the platform ABI. To do that, +// XPTC_InvokeByIndex() has to determine the method to call via vtable +// access. The parameters for the method are read from the +// nsXPTCVariant* and prepared for th native ABI. For the Linux/PPC +// ABI this means that the first 8 integral and floating point +// parameters are passed in registers. + +#include "xptcprivate.h" + +// 8 integral parameters are passed in registers +#define GPR_COUNT 8 + +// 8 floating point parameters are passed in registers, floats are +// promoted to doubles when passed in registers +#define FPR_COUNT 8 + +extern "C" PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + return PRUint32(((paramCount * 2) + 3) & ~3); +} + +extern "C" void +invoke_copy_to_stack(PRUint32* d, + PRUint32 paramCount, + nsXPTCVariant* s, + PRUint32* gpregs, + double* fpregs) +{ + PRUint32 gpr = 1; // skip one GP reg for 'that' + PRUint32 fpr = 0; + PRUint32 tempu32; + PRUint64 tempu64; + + for(uint32 i = 0; i < paramCount; i++, s++) { + if(s->IsPtrData()) + tempu32 = (PRUint32) s->ptr; + else { + switch(s->type) { + case nsXPTType::T_FLOAT: break; + case nsXPTType::T_DOUBLE: break; + case nsXPTType::T_I8: tempu32 = s->val.i8; break; + case nsXPTType::T_I16: tempu32 = s->val.i16; break; + case nsXPTType::T_I32: tempu32 = s->val.i32; break; + case nsXPTType::T_I64: tempu64 = s->val.i64; break; + case nsXPTType::T_U8: tempu32 = s->val.u8; break; + case nsXPTType::T_U16: tempu32 = s->val.u16; break; + case nsXPTType::T_U32: tempu32 = s->val.u32; break; + case nsXPTType::T_U64: tempu64 = s->val.u64; break; + case nsXPTType::T_BOOL: tempu32 = s->val.b; break; + case nsXPTType::T_CHAR: tempu32 = s->val.c; break; + case nsXPTType::T_WCHAR: tempu32 = s->val.wc; break; + default: tempu32 = (PRUint32) s->val.p; break; + } + } + + if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) { + if (fpr < FPR_COUNT) + fpregs[fpr++] = s->val.d; + else { + if ((PRUint32) d & 4) d++; // doubles are 8-byte aligned on stack + *((double*) d) = s->val.d; + d += 2; + } + } + else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) { + if (fpr < FPR_COUNT) + fpregs[fpr++] = s->val.f; // if passed in registers, floats are promoted to doubles + else + *((float*) d++) = s->val.f; + } + else if (!s->IsPtrData() && (s->type == nsXPTType::T_I64 + || s->type == nsXPTType::T_U64)) { + if ((gpr + 1) < GPR_COUNT) { + if (gpr & 1) gpr++; // longlongs are aligned in odd/even register pairs, eg. r5/r6 + *((PRUint64*) &gpregs[gpr]) = tempu64; + gpr += 2; + } + else { + if ((PRUint32) d & 4) d++; // longlongs are 8-byte aligned on stack + *((PRUint64*) d) = tempu64; + d += 2; + } + } + else { + if (gpr < GPR_COUNT) + gpregs[gpr++] = tempu32; + else + *d++ = tempu32; + } + + } +} + +extern "C" +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_netbsd.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_netbsd.cpp new file mode 100644 index 00000000..0de8ea62 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_netbsd.cpp @@ -0,0 +1,147 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Franz.Sirl-kernel@lauterbach.com (Franz Sirl) + * beard@netscape.com (Patrick Beard) + * waterson@netscape.com (Chris Waterson) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Platform specific code to invoke XPCOM methods on native objects + +// The purpose of XPTC_InvokeByIndex() is to map a platform +// indepenpent call to the platform ABI. To do that, +// XPTC_InvokeByIndex() has to determine the method to call via vtable +// access. The parameters for the method are read from the +// nsXPTCVariant* and prepared for th native ABI. For the Linux/PPC +// ABI this means that the first 8 integral and floating point +// parameters are passed in registers. + +#include "xptcprivate.h" + +// 8 integral parameters are passed in registers +#define GPR_COUNT 8 + +// 8 floating point parameters are passed in registers, floats are +// promoted to doubles when passed in registers +#define FPR_COUNT 8 + +extern "C" PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + return PRUint32(((paramCount * 2) + 3) & ~3); +} + +extern "C" void +invoke_copy_to_stack(PRUint32* d, + PRUint32 paramCount, + nsXPTCVariant* s, + PRUint32* gpregs, + double* fpregs) +{ + PRUint32 gpr = 1; // skip one GP reg for 'that' + PRUint32 fpr = 0; + PRUint32 tempu32; + PRUint64 tempu64; + + for(uint32 i = 0; i < paramCount; i++, s++) { + if(s->IsPtrData()) + tempu32 = (PRUint32) s->ptr; + else { + switch(s->type) { + case nsXPTType::T_FLOAT: break; + case nsXPTType::T_DOUBLE: break; + case nsXPTType::T_I8: tempu32 = s->val.i8; break; + case nsXPTType::T_I16: tempu32 = s->val.i16; break; + case nsXPTType::T_I32: tempu32 = s->val.i32; break; + case nsXPTType::T_I64: tempu64 = s->val.i64; break; + case nsXPTType::T_U8: tempu32 = s->val.u8; break; + case nsXPTType::T_U16: tempu32 = s->val.u16; break; + case nsXPTType::T_U32: tempu32 = s->val.u32; break; + case nsXPTType::T_U64: tempu64 = s->val.u64; break; + case nsXPTType::T_BOOL: tempu32 = s->val.b; break; + case nsXPTType::T_CHAR: tempu32 = s->val.c; break; + case nsXPTType::T_WCHAR: tempu32 = s->val.wc; break; + default: tempu32 = (PRUint32) s->val.p; break; + } + } + + if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) { + if (fpr < FPR_COUNT) + fpregs[fpr++] = s->val.d; + else { + if ((PRUint32) d & 4) d++; // doubles are 8-byte aligned on stack + *((double*) d) = s->val.d; + d += 2; + if (gpr < GPR_COUNT) + gpr += 2; + } + } + else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) { + if (fpr < FPR_COUNT) + fpregs[fpr++] = s->val.f; // if passed in registers, floats are promoted to doubles + else { + *((float*) d) = s->val.f; + d += 1; + if (gpr < GPR_COUNT) + gpr += 1; + } + } + else if (!s->IsPtrData() && (s->type == nsXPTType::T_I64 + || s->type == nsXPTType::T_U64)) { + if ((gpr + 1) < GPR_COUNT) { + if (gpr & 1) gpr++; // longlongs are aligned in odd/even register pairs, eg. r5/r6 + *((PRUint64*) &gpregs[gpr]) = tempu64; + gpr += 2; + } + else { + if ((PRUint32) d & 4) d++; // longlongs are 8-byte aligned on stack + *((PRUint64*) d) = tempu64; + d += 2; + } + } + else { + if (gpr < GPR_COUNT) + gpregs[gpr++] = tempu32; + else + *d++ = tempu32; + } + + } +} + +extern "C" +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_rhapsody.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_rhapsody.cpp new file mode 100644 index 00000000..9a08acfd --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_rhapsody.cpp @@ -0,0 +1,145 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +extern "C" uint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 result = 0; + /* fprintf(stderr,"invoke_count_words(%d,%p)\n",paramCount, s);*/ + + for(PRUint32 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; + } + } + return result; +} + +extern "C" void +invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s, double *fprData) +{ + PRUint32 fpCount = 0; + + /* fprintf(stderr,"invoke_copy_to_stack(%p, %d, %p, %p)\n", d, paramCount, s, fprData);*/ + + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : *((PRInt32*) d) = s->val.i8; break; + case nsXPTType::T_I16 : *((PRInt32*) d) = s->val.i16; break; + case nsXPTType::T_I32 : *((PRInt32*) d) = s->val.i32; break; + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U8 : *((PRUint32*) d) = s->val.u8; break; + case nsXPTType::T_U16 : *((PRUint32*)d) = s->val.u16; break; + case nsXPTType::T_U32 : *((PRUint32*)d) = s->val.u32; break; + case nsXPTType::T_U64 : *((PRUint64*)d) = s->val.u64; d++; break; + case nsXPTType::T_FLOAT : *((float*) d) = s->val.f; + if (fpCount < 13) + fprData[fpCount++] = s->val.f; + break; + case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; + if (fpCount < 13) + fprData[fpCount++] = s->val.d; + break; + case nsXPTType::T_BOOL : *((PRBool*) d) = s->val.b; break; + case nsXPTType::T_CHAR : *((PRInt32*) d) = s->val.c; break; + case nsXPTType::T_WCHAR : *((PRUint32*) 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, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +extern "C" +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + return _XPTC_InvokeByIndex(that, methodIndex, paramCount, params); +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_netbsd.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_netbsd.cpp new file mode 100644 index 00000000..fb2af366 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_netbsd.cpp @@ -0,0 +1,156 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* 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" PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 result = 0; + for(PRUint32 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" PRUint32 +invoke_copy_to_stack(PRUint32* d, PRUint32 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 *l_d = d; + nsXPTCVariant *l_s = s; + uint32 l_paramCount = paramCount; + uint32 regCount = 0; // return the number of registers to load from the stack + + typedef struct { + uint32 hi; + uint32 lo; + } DU; // have to move 64 bit entities as 32 bit halves since + // stack slots are not guaranteed 16 byte aligned + + for(uint32 i = 0; i < l_paramCount; i++, l_d++, l_s++) + { + if (regCount < 5) regCount++; + if(l_s->IsPtrData()) + { + *((void**)l_d) = l_s->ptr; + continue; + } + switch(l_s->type) + { + case nsXPTType::T_I8 : *((int32*) l_d) = l_s->val.i8; break; + case nsXPTType::T_I16 : *((int32*) l_d) = l_s->val.i16; break; + case nsXPTType::T_I32 : *((int32*) l_d) = l_s->val.i32; break; + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + case nsXPTType::T_DOUBLE : *((uint32*) l_d++) = ((DU *)l_s)->hi; + if (regCount < 5) regCount++; + *((uint32*) l_d) = ((DU *)l_s)->lo; + break; + case nsXPTType::T_U8 : *((uint32*) l_d) = l_s->val.u8; break; + case nsXPTType::T_U16 : *((uint32*) l_d) = l_s->val.u16; break; + case nsXPTType::T_U32 : *((uint32*) l_d) = l_s->val.u32; break; + case nsXPTType::T_FLOAT : *((float*) l_d) = l_s->val.f; break; + case nsXPTType::T_BOOL : *((PRBool*) l_d) = l_s->val.b; break; + case nsXPTType::T_CHAR : *((uint32*) l_d) = l_s->val.c; break; + case nsXPTType::T_WCHAR : *((int32*)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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_solaris.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_solaris.cpp new file mode 100644 index 00000000..fb2af366 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_solaris.cpp @@ -0,0 +1,156 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* 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" PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 result = 0; + for(PRUint32 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" PRUint32 +invoke_copy_to_stack(PRUint32* d, PRUint32 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 *l_d = d; + nsXPTCVariant *l_s = s; + uint32 l_paramCount = paramCount; + uint32 regCount = 0; // return the number of registers to load from the stack + + typedef struct { + uint32 hi; + uint32 lo; + } DU; // have to move 64 bit entities as 32 bit halves since + // stack slots are not guaranteed 16 byte aligned + + for(uint32 i = 0; i < l_paramCount; i++, l_d++, l_s++) + { + if (regCount < 5) regCount++; + if(l_s->IsPtrData()) + { + *((void**)l_d) = l_s->ptr; + continue; + } + switch(l_s->type) + { + case nsXPTType::T_I8 : *((int32*) l_d) = l_s->val.i8; break; + case nsXPTType::T_I16 : *((int32*) l_d) = l_s->val.i16; break; + case nsXPTType::T_I32 : *((int32*) l_d) = l_s->val.i32; break; + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + case nsXPTType::T_DOUBLE : *((uint32*) l_d++) = ((DU *)l_s)->hi; + if (regCount < 5) regCount++; + *((uint32*) l_d) = ((DU *)l_s)->lo; + break; + case nsXPTType::T_U8 : *((uint32*) l_d) = l_s->val.u8; break; + case nsXPTType::T_U16 : *((uint32*) l_d) = l_s->val.u16; break; + case nsXPTType::T_U32 : *((uint32*) l_d) = l_s->val.u32; break; + case nsXPTType::T_FLOAT : *((float*) l_d) = l_s->val.f; break; + case nsXPTType::T_BOOL : *((PRBool*) l_d) = l_s->val.b; break; + case nsXPTType::T_CHAR : *((uint32*) l_d) = l_s->val.c; break; + case nsXPTType::T_WCHAR : *((int32*)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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparcv9_solaris.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparcv9_solaris.cpp new file mode 100644 index 00000000..83b28ebb --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparcv9_solaris.cpp @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> + * Chris Seawood <cls@seawood.org> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +#if !defined(__sparc) && !defined(__sparc__) +#error "This code is for Sparc only" +#endif + +/* Prototype specifies unmangled function name */ +extern "C" PRUint64 +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s); + +extern "C" PRUint64 +invoke_copy_to_stack(PRUint64* d, PRUint32 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. + */ + PRUint64 *l_d = d; + nsXPTCVariant *l_s = s; + PRUint64 l_paramCount = paramCount; + PRUint64 regCount = 0; // return the number of registers to load from the stack + + for(PRUint64 i = 0; i < l_paramCount; i++, l_d++, l_s++) + { + if (regCount < 5) regCount++; + + if (l_s->IsPtrData()) + { + *l_d = (PRUint64)l_s->ptr; + continue; + } + switch (l_s->type) + { + case nsXPTType::T_I8 : *((PRInt64*)l_d) = l_s->val.i8; break; + case nsXPTType::T_I16 : *((PRInt64*)l_d) = l_s->val.i16; break; + case nsXPTType::T_I32 : *((PRInt64*)l_d) = l_s->val.i32; break; + case nsXPTType::T_I64 : *((PRInt64*)l_d) = l_s->val.i64; break; + + case nsXPTType::T_U8 : *((PRUint64*)l_d) = l_s->val.u8; break; + case nsXPTType::T_U16 : *((PRUint64*)l_d) = l_s->val.u16; break; + case nsXPTType::T_U32 : *((PRUint64*)l_d) = l_s->val.u32; break; + case nsXPTType::T_U64 : *((PRUint64*)l_d) = l_s->val.u64; break; + + /* in the case of floats, we want to put the bits in to the + 64bit space right justified... floats in the paramter array on + sparcv9 use odd numbered registers.. %f1, %f3, so we have to skip + the space that would be occupied by %f0, %f2, etc. + */ + case nsXPTType::T_FLOAT : *(((float*)l_d) + 1) = l_s->val.f; break; + case nsXPTType::T_DOUBLE: *((double*)l_d) = l_s->val.d; break; + case nsXPTType::T_BOOL : *((PRBool*)l_d) = l_s->val.b; break; + case nsXPTType::T_CHAR : *((PRUint64*)l_d) = l_s->val.c; break; + case nsXPTType::T_WCHAR : *((PRInt64*)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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_x86.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_x86.cpp new file mode 100644 index 00000000..76445fa4 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_x86.cpp @@ -0,0 +1,187 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mark Mentovai <mark@moxienet.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" +#include "xptc_platforms_unixish_x86.h" + +extern "C" { + +static void +invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d) +{ + for(PRUint32 i = paramCount; i >0; i--, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + +/* XXX: the following line is here (rather than as the default clause in + * the following switch statement) so that the Sun native compiler + * will generate the correct assembly code on the Solaris Intel + * platform. See the comments in bug #28817 for more details. + */ + + *((void**)d) = s->val.p; + + switch(s->type) + { + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U64 : *((PRUint64*)d) = s->val.u64; d++; break; + case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; break; + } + } +} + +} + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ +#ifdef __GNUC__ /* Gnu compiler. */ + PRUint32 result; + /* Each param takes at most 2, 4-byte words + It doesn't matter if we push too many words, and calculating the exact + amount takes time. */ + PRUint32 n = paramCount << 3; + void (*fn_copy) (unsigned int, nsXPTCVariant *, PRUint32 *) = invoke_copy_to_stack; + int temp1, temp2; + + /* These are only significant when KEEP_STACK_16_BYTE_ALIGNED is + defined. Otherwise, they're just placeholders to keep the parameter + indices the same for aligned and unaligned users in the inline asm + block. */ + unsigned int saved_esp; + + __asm__ __volatile__( +#ifdef KEEP_STACK_16_BYTE_ALIGNED + "movl %%esp, %3\n\t" +#endif + "subl %8, %%esp\n\t" /* make room for params */ +#ifdef KEEP_STACK_16_BYTE_ALIGNED + /* For the second CALL, there will be one parameter before the ones + copied by invoke_copy_to_stack. Make sure that the stack will be + aligned for that CALL. */ + "subl $4, %%esp\n\t" + "andl $0xfffffff0, %%esp\n\t" + /* For the first CALL, there are three parameters. Leave padding to + ensure alignment. */ + "subl $4, %%esp\n\t" + /* The third parameter to invoke_copy_to_stack is the destination pointer. + It needs to point into the parameter area prepared for the second CALL, + leaving room for the |that| parameter. This reuses |n|, which was + the stack space to reserve, but that's OK because it's no longer needed + if the stack is being kept aligned. */ + "leal 8(%%esp), %8\n\t" + "pushl %8\n\t" +#else + "pushl %%esp\n\t" +#endif + "pushl %7\n\t" + "pushl %6\n\t" + "call *%9\n\t" /* copy params */ +#ifdef KEEP_STACK_16_BYTE_ALIGNED + /* The stack is still aligned from the first CALL. Keep it aligned for + the next one by popping past the parameters from the first CALL and + leaving space for the first (|that|) parameter for the second CALL. */ + "addl $0x14, %%esp\n\t" +#else + "addl $0xc, %%esp\n\t" +#endif + "movl %4, %%ecx\n\t" +#ifdef CFRONT_STYLE_THIS_ADJUST + "movl (%%ecx), %%edx\n\t" + "movl %5, %%eax\n\t" /* function index */ + "shl $3, %%eax\n\t" /* *= 8 */ + "addl $8, %%eax\n\t" /* += 8 skip first entry */ + "addl %%eax, %%edx\n\t" + "movswl (%%edx), %%eax\n\t" /* 'this' offset */ + "addl %%eax, %%ecx\n\t" + "pushl %%ecx\n\t" + "addl $4, %%edx\n\t" /* += 4, method pointer */ +#else /* THUNK_BASED_THIS_ADJUST */ + "pushl %%ecx\n\t" + "movl (%%ecx), %%edx\n\t" + "movl %5, %%eax\n\t" /* function index */ +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + "leal (%%edx,%%eax,4), %%edx\n\t" +#else /* not G++ V3 ABI */ + "leal 8(%%edx,%%eax,4), %%edx\n\t" +#endif /* G++ V3 ABI */ +#endif + "call *(%%edx)\n\t" /* safe to not cleanup esp */ +#ifdef KEEP_STACK_16_BYTE_ALIGNED + "movl %3, %%esp\n\t" +#else + "addl $4, %%esp\n\t" + "addl %8, %%esp" +#endif + : "=a" (result), /* %0 */ + "=c" (temp1), /* %1 */ + "=d" (temp2), /* %2 */ +#ifdef KEEP_STACK_16_BYTE_ALIGNED + "=&g" (saved_esp) /* %3 */ +#else + /* Don't waste a register, this isn't used if alignment is unimportant */ + "=m" (saved_esp) /* %3 */ +#endif + : "g" (that), /* %4 */ + "g" (methodIndex), /* %5 */ + "1" (paramCount), /* %6 */ + "2" (params), /* %7 */ +#ifdef KEEP_STACK_16_BYTE_ALIGNED + /* Must be in a register, it's the target of an LEA instruction */ + "r" (n), /* %8 */ +#else + "g" (n), /* %8 */ +#endif + "0" (fn_copy) /* %9 */ + : "memory" + ); + + return result; + +#else +#error "can't find a compiler to use" +#endif /* __GNUC__ */ + +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unsupported.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unsupported.cpp new file mode 100644 index 00000000..88219d8d --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unsupported.cpp @@ -0,0 +1,48 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + NS_ASSERTION(0,"XPTC_InvokeByIndex called on unsupported platform"); + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_linux.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_linux.cpp new file mode 100644 index 00000000..b017c741 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_linux.cpp @@ -0,0 +1,227 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org Code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Platform specific code to invoke XPCOM methods on native objects + +#include "xptcprivate.h" + +// 6 integral parameters are passed in registers +const PRUint32 GPR_COUNT = 6; + +// 8 floating point parameters are passed in SSE registers +const PRUint32 FPR_COUNT = 8; + +// Remember that these 'words' are 64-bit long +static inline void +invoke_count_words(PRUint32 paramCount, nsXPTCVariant * s, + PRUint32 & nr_gpr, PRUint32 & nr_fpr, PRUint32 & nr_stack) +{ + nr_gpr = 1; // skip one GP register for 'that' + nr_fpr = 0; + nr_stack = 0; + + /* Compute number of eightbytes of class MEMORY. */ + for (uint32 i = 0; i < paramCount; i++, s++) { + if (!s->IsPtrData() + && (s->type == nsXPTType::T_FLOAT || s->type == nsXPTType::T_DOUBLE)) { + if (nr_fpr < FPR_COUNT) + nr_fpr++; + else + nr_stack++; + } + else { + if (nr_gpr < GPR_COUNT) + nr_gpr++; + else + nr_stack++; + } + } +} + +static void +invoke_copy_to_stack(PRUint64 * d, PRUint32 paramCount, nsXPTCVariant * s, + PRUint64 * gpregs, double * fpregs) +{ + PRUint32 nr_gpr = 1; // skip one GP register for 'that' + PRUint32 nr_fpr = 0; + PRUint64 value; + + for (uint32 i = 0; i < paramCount; i++, s++) { + if (s->IsPtrData()) + value = (PRUint64) s->ptr; + else { + switch (s->type) { + case nsXPTType::T_FLOAT: break; + case nsXPTType::T_DOUBLE: break; + case nsXPTType::T_I8: value = s->val.i8; break; + case nsXPTType::T_I16: value = s->val.i16; break; + case nsXPTType::T_I32: value = s->val.i32; break; + case nsXPTType::T_I64: value = s->val.i64; break; + case nsXPTType::T_U8: value = s->val.u8; break; + case nsXPTType::T_U16: value = s->val.u16; break; + case nsXPTType::T_U32: value = s->val.u32; break; + case nsXPTType::T_U64: value = s->val.u64; break; + case nsXPTType::T_BOOL: value = s->val.b; break; + case nsXPTType::T_CHAR: value = s->val.c; break; + case nsXPTType::T_WCHAR: value = s->val.wc; break; + default: value = (PRUint64) s->val.p; break; + } + } + + if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) { + if (nr_fpr < FPR_COUNT) + fpregs[nr_fpr++] = s->val.d; + else { + *((double *)d) = s->val.d; + d++; + } + } + else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) { + if (nr_fpr < 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. + fpregs[nr_fpr++] = s->val.d; + else { + *((float *)d) = s->val.f; + d++; + } + } + else { + if (nr_gpr < GPR_COUNT) + gpregs[nr_gpr++] = value; + else + *d++ = value; + } + } +} + +extern "C" +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports * that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant * params) +{ + PRUint32 nr_gpr, nr_fpr, nr_stack; + invoke_count_words(paramCount, params, nr_gpr, nr_fpr, nr_stack); + + // Stack, if used, must be 16-bytes aligned + if (nr_stack) + nr_stack = (nr_stack + 1) & ~1; + +#ifndef VBOX_WITH_GCC_SANITIZER + // Load parameters to stack, if necessary + PRUint64 *stack = (PRUint64 *) __builtin_alloca(nr_stack * 8); +#else + typedef struct { PRUint64 stack[20]; } methodStack; + if (nr_stack > 20) + return NS_ERROR_CALL_FAILED; + methodStack stack; +#endif + PRUint64 gpregs[GPR_COUNT]; + double fpregs[FPR_COUNT]; +#ifndef VBOX_WITH_GCC_SANITIZER + invoke_copy_to_stack(stack, paramCount, params, gpregs, fpregs); +#else + invoke_copy_to_stack(stack.stack, paramCount, params, gpregs, fpregs); +#endif + + // Load FPR registers from fpregs[] + register double d0 asm("xmm0"); + register double d1 asm("xmm1"); + register double d2 asm("xmm2"); + register double d3 asm("xmm3"); + register double d4 asm("xmm4"); + register double d5 asm("xmm5"); + register double d6 asm("xmm6"); + register double d7 asm("xmm7"); + + switch (nr_fpr) { +#define ARG_FPR(N) \ + case N+1: d##N = fpregs[N]; + ARG_FPR(7); + ARG_FPR(6); + ARG_FPR(5); + ARG_FPR(4); + ARG_FPR(3); + ARG_FPR(2); + ARG_FPR(1); + ARG_FPR(0); + case 0:; +#undef ARG_FPR + } + + // Load GPR registers from gpregs[] + register PRUint64 a0 asm("rdi"); + register PRUint64 a1 asm("rsi"); + register PRUint64 a2 asm("rdx"); + register PRUint64 a3 asm("rcx"); + register PRUint64 a4 asm("r8"); + register PRUint64 a5 asm("r9"); + + switch (nr_gpr) { +#define ARG_GPR(N) \ + case N+1: a##N = gpregs[N]; + ARG_GPR(5); + ARG_GPR(4); + ARG_GPR(3); + ARG_GPR(2); + ARG_GPR(1); + case 1: a0 = (PRUint64) that; + case 0:; +#undef ARG_GPR + } + + // Ensure that assignments to SSE registers won't be optimized away + asm("" :: + "x" (d0), "x" (d1), "x" (d2), "x" (d3), + "x" (d4), "x" (d5), "x" (d6), "x" (d7)); + + // Get pointer to method + PRUint64 methodAddress = *((PRUint64 *)that); + methodAddress += 8 * methodIndex; + methodAddress = *((PRUint64 *)methodAddress); + +#ifndef VBOX_WITH_GCC_SANITIZER + typedef PRUint32 (*Method)(PRUint64, PRUint64, PRUint64, PRUint64, PRUint64, PRUint64); + PRUint32 result = ((Method)methodAddress)(a0, a1, a2, a3, a4, a5); +#else + typedef PRUint32 (*Method)(PRUint64, PRUint64, PRUint64, PRUint64, PRUint64, PRUint64, methodStack); + PRUint32 result = ((Method)methodAddress)(a0, a1, a2, a3, a4, a5, stack); +#endif + return result; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_solaris.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_solaris.cpp new file mode 100644 index 00000000..14ecb2d8 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_solaris.cpp @@ -0,0 +1,285 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org Code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" +#include "xptc_platforms_unixish_x86.h" +#ifdef VBOX +# include <iprt/alloca.h> +#endif + +extern "C" { + +// Remember that these 'words' are 32bit DWORDS + +static PRUint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + PRUint32 result = 0; + for(PRUint32 i = 0; i < paramCount; i++, s++) + { + if(s->IsPtrData()) + { + result++; + continue; + } + result++; + switch(s->type) + { + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + case nsXPTType::T_DOUBLE : + result++; + break; + } + } + return result; +} + +static void +invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d) +{ + for(PRUint32 i = 0; i < paramCount; i++, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + +/* XXX: the following line is here (rather than as the default clause in + * the following switch statement) so that the Sun native compiler + * will generate the correct assembly code on the Solaris Intel + * platform. See the comments in bug #28817 for more details. + */ + + *((void**)d) = s->val.p; + + switch(s->type) + { + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U64 : *((PRUint64*)d) = s->val.u64; d++; break; + case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; break; + } + } +} + +} + +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ +#ifdef __GNUC__ /* Gnu compiler. */ + PRUint32 result; + PRUint32 n = invoke_count_words (paramCount, params) * 4; + int temp1, temp2, temp3; + +# ifdef VBOX + /* This is for dealing with gcc 4.5.2 not using registers for 'g' parameters + and instead trying to get things like 'that' via %esp after we've changed it. */ +# if 1 /* safe version. */ + void (*fn_copy) (unsigned int, nsXPTCVariant *, PRUint32 *) = invoke_copy_to_stack; + struct Combined + { + PRUint32 that; /* offset: 0 */ + PRUint32 pfn; /* offset: 4 */ + PRUint32 savedEsp; /* offset: 8 */ + PRUint32 paramCount; /* offset: 12 */ + PRUint32 params; /* offset: 16 */ + } Combined; +# ifdef CFRONT_STYLE_THIS_ADJUST + struct CFRONTVTE { uintptr_t off, pfn } *pVtab = *(struct CFRONTVTE **)that; + Combined.that = (uintptr_t)that + pVtab[methodIndex + 1].off; + Combined.pfn = pVtab[methodIndex + 1].pfn; +# elif defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + Combined.that = (uintptr_t)that; + Combined.pfn = (*(uintptr_t **)that)[methodIndex]; +# else /* not G++ V3 ABI */ + Combined.that = (uintptr_t)that; + Combined.pfn = (*(uintptr_t **)that)[2 + methodIndex]; +# endif /* G++ V3 ABI */ + Combined.paramCount = paramCount; + Combined.params = (uintptr_t)params; + + __asm__ __volatile__( + "mov %%esp, 8(%%esi)\n\t" /* savedEsp = %esp */ + "subl %1, %%esp\n\t" /* make room for params */ + + /* Call invoke_count_words to copy the parameters. */ + "pushl %%esp\n\t" /* arg2: dest */ + "pushl 16(%%esi)\n\t" /* arg1: params */ + "pushl 12(%%esi)\n\t" /* arg0: paramCount */ + "call *%0\n\t" + "addl $0xc, %%esp\n\t" + + /* Push the this pointer. */ + "pushl (%%esi)\n\t" /* that */ + "call *4(%%esi)\n\t" + "mov 8(%%esi), %%esp\n\t" + : "=a" (result), /* %0 */ + "=c" (temp1), /* %1 */ + "=d" (temp2) /* %2 */ + : "S" (&Combined), /* %3 */ + "0" (fn_copy), + "1" (n) + : "memory" + ); + +# else /* Small version; ASSUMES nothing important gets put on the stack after the the alloca. */ + uintptr_t *pauStack = (uintptr_t *)alloca(n + sizeof(uintptr_t)); + invoke_copy_to_stack(paramCount, params, &pauStack[1]); +# ifdef CFRONT_STYLE_THIS_ADJUST + struct CFRONTVTE { uintptr_t off, pfn } *pVtab = *(struct CFRONTVTE **)that; + pauStack[0] = (uintptr_t)that + pVtab[methodIndex + 1].off; + uintptr_t pfn = pVtab[methodIndex + 1].pfn; +# elif defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + pauStack[0] = (uintptr_t)that; + uintptr_t pfn = (*(uintptr_t **)that)[methodIndex]; +# else /* not G++ V3 ABI */ + pauStack[0] = (uintptr_t)that; + uintptr_t pfn = (*(uintptr_t **)that)[2 + methodIndex]; +# endif /* G++ V3 ABI */ + + __asm__ __volatile__( + "xchg %%esp, %3\n\t" /* save+load %esp */ + "call *%0\n\t" + "xchg %%esp, %3\n\t" /* restore %esp */ + : "=a" (result), /* %0 */ + "=c" (temp1), /* %1 */ + "=d" (temp2) /* %2 */ + : "S" (pauStack), /* %3 */ + "0" (pfn) + : "memory" + ); +# endif + +# else /* !VBOX */ + void (*fn_copy) (unsigned int, nsXPTCVariant *, PRUint32 *) = invoke_copy_to_stack; + __asm__ __volatile__( + "subl %8, %%esp\n\t" /* make room for params */ + "pushl %%esp\n\t" + "pushl %7\n\t" + "pushl %6\n\t" + "call *%0\n\t" /* copy params */ + "addl $0xc, %%esp\n\t" + "movl %4, %%ecx\n\t" +#ifdef CFRONT_STYLE_THIS_ADJUST + "movl (%%ecx), %%edx\n\t" + "movl %5, %%eax\n\t" /* function index */ + "shl $3, %%eax\n\t" /* *= 8 */ + "addl $8, %%eax\n\t" /* += 8 skip first entry */ + "addl %%eax, %%edx\n\t" + "movswl (%%edx), %%eax\n\t" /* 'this' offset */ + "addl %%eax, %%ecx\n\t" + "pushl %%ecx\n\t" + "addl $4, %%edx\n\t" /* += 4, method pointer */ +#else /* THUNK_BASED_THIS_ADJUST */ + "pushl %%ecx\n\t" + "movl (%%ecx), %%edx\n\t" + "movl %5, %%eax\n\t" /* function index */ +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + "leal (%%edx,%%eax,4), %%edx\n\t" +#else /* not G++ V3 ABI */ + "leal 8(%%edx,%%eax,4), %%edx\n\t" +#endif /* G++ V3 ABI */ +#endif + "call *(%%edx)\n\t" /* safe to not cleanup esp */ + "addl $4, %%esp\n\t" + "addl %8, %%esp" + : "=a" (result), /* %0 */ + "=c" (temp1), /* %1 */ + "=d" (temp2), /* %2 */ + "=g" (temp3) /* %3 */ + : "g" (that), /* %4 */ + "g" (methodIndex), /* %5 */ + "1" (paramCount), /* %6 */ + "2" (params), /* %7 */ + "g" (n), /* %8 */ + "0" (fn_copy) /* %3 */ + : "memory" + ); +# endif /* !VBOX */ + + return result; +#elif defined(__SUNPRO_CC) /* Sun Workshop Compiler. */ + +asm( + "\n\t /: PRUint32 n = invoke_count_words (paramCount, params) * 4;" + + "\n\t pushl %ebx / preserve ebx" + "\n\t pushl %esi / preserve esi" + "\n\t movl %esp, %ebx / save address of pushed esi and ebx" + + "\n\t pushl 20(%ebp) / \"params\"" + "\n\t pushl 16(%ebp) / \"paramCount\"" + "\n\t call invoke_count_words" + "\n\t mov %ebx, %esp / restore esp" + + "\n\t sall $2,%eax" + "\n\t subl %eax, %esp / make room for arguments" + "\n\t movl %esp, %esi / save new esp" + + "\n\t pushl %esp" + "\n\t pushl 20(%ebp) / \"params\"" + "\n\t pushl 16(%ebp) / \"paramCount\"" + "\n\t call invoke_copy_to_stack / copy params" + "\n\t movl %esi, %esp / restore new esp" + + "\n\t movl 8(%ebp),%ecx / \"that\"" + "\n\t pushl %ecx / \"that\"" + "\n\t movl (%ecx), %edx" + "\n\t movl 12(%ebp), %eax / function index: \"methodIndex\"" + "\n\t movl 8(%edx,%eax,4), %edx" + + "\n\t call *%edx" + "\n\t mov %ebx, %esp" + "\n\t popl %esi" + "\n\t popl %ebx" +); + +/* result == %eax */ + if(0) /* supress "*** is expected to return a value." error */ + return 0; + +#else +#error "can't find a compiler to use" +#endif /* __GNUC__ */ + +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_amd64_darwin.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_amd64_darwin.cpp new file mode 100644 index 00000000..5b55c930 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_amd64_darwin.cpp @@ -0,0 +1,243 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org Code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Implement shared vtbl methods. + +#include "xptcprivate.h" + +// The Linux/x86-64 ABI passes the first 6 integer parameters and the +// first 8 floating point parameters in registers (rdi, rsi, rdx, rcx, +// r8, r9 and xmm0-xmm7), no stack space is allocated for these by the +// caller. The rest of the parameters are passed in the callers stack +// area. + +const PRUint32 PARAM_BUFFER_COUNT = 16; +const PRUint32 GPR_COUNT = 6; +const PRUint32 FPR_COUNT = 8; + +// PrepareAndDispatch() is called by SharedStub() and calls the actual method. +// +// - 'args[]' contains the arguments passed on stack +// - 'gpregs[]' contains the arguments passed in integer registers +// - 'fpregs[]' contains the arguments passed in floating point registers +// +// The parameters are mapped into an array of type 'nsXPTCMiniVariant' +// and then the method gets called. + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase * self, PRUint32 methodIndex, + PRUint64 * args, PRUint64 * gpregs, double *fpregs) +{ + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info = NULL; + PRUint32 paramCount; + PRUint32 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + if (!iface_info) + return NS_ERROR_UNEXPECTED; + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no method info"); + if (!info) + return NS_ERROR_UNEXPECTED; + + 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"); + if (!dispatchParams) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint64* ap = args; + PRUint32 nr_gpr = 1; // skip one GPR register for 'that' + PRUint32 nr_fpr = 0; + PRUint64 value; + + 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 == nsXPTType::T_DOUBLE) { + if (nr_fpr < FPR_COUNT) + dp->val.d = fpregs[nr_fpr++]; + else + dp->val.d = *(double*) ap++; + continue; + } + else if (!param.IsOut() && type == nsXPTType::T_FLOAT) { + if (nr_fpr < 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*) ap++; + else + dp->val.f = *(float*) ap++; + continue; + } + else { + if (nr_gpr < GPR_COUNT) + value = gpregs[nr_gpr++]; + else + value = *ap++; + } + + if (param.IsOut() || !type.IsArithmetic()) { + dp->val.p = (void*) value; + continue; + } + + switch (type) { + case nsXPTType::T_I8: dp->val.i8 = (PRInt8) value; break; + case nsXPTType::T_I16: dp->val.i16 = (PRInt16) value; break; + case nsXPTType::T_I32: dp->val.i32 = (PRInt32) value; break; + case nsXPTType::T_I64: dp->val.i64 = (PRInt64) value; break; + case nsXPTType::T_U8: dp->val.u8 = (PRUint8) value; break; + case nsXPTType::T_U16: dp->val.u16 = (PRUint16) value; break; + case nsXPTType::T_U32: dp->val.u32 = (PRUint32) value; break; + case nsXPTType::T_U64: dp->val.u64 = (PRUint64) value; break; + case nsXPTType::T_BOOL: dp->val.b = (PRBool) value; break; + case nsXPTType::T_CHAR: dp->val.c = (char) value; break; + case nsXPTType::T_WCHAR: dp->val.wc = (wchar_t) value; break; + + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if (dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ +// Darwin/AMD64 uses gcc >= 3.1 +#define STUB_ENTRY(n) \ +asm(".text\n\t" \ + ".align 2\n\t" \ + ".if " #n " < 10\n\t" \ + ".globl __ZN14nsXPTCStubBase5Stub" #n "Ev\n\t" \ + /*".type __ZN14nsXPTCStubBase5Stub" #n "Ev,@function\n"*/ \ + "__ZN14nsXPTCStubBase5Stub" #n "Ev:\n\t" \ + ".elseif " #n " < 100\n\t" \ + ".globl __ZN14nsXPTCStubBase6Stub" #n "Ev\n\t" \ + /*".type __ZN14nsXPTCStubBase6Stub" #n "Ev,@function\n"*/ \ + "__ZN14nsXPTCStubBase6Stub" #n "Ev:\n\t" \ + ".elseif " #n " < 1000\n\t" \ + ".globl __ZN14nsXPTCStubBase7Stub" #n "Ev\n\t" \ + /*".type __ZN14nsXPTCStubBase7Stub" #n "Ev,@function\n"*/ \ + "__ZN14nsXPTCStubBase7Stub" #n "Ev:\n\t" \ + ".else\n\t" \ + ".err \"stub number " #n " >= 1000 not yet supported\"\n\t" \ + ".endif\n\t" \ + "movl $" #n ", %eax\n\t" \ + "jmp SharedStub\n\t" \ + ".if " #n " < 10\n\t" \ + /*".size __ZN14nsXPTCStubBase5Stub" #n "Ev,.-__ZN14nsXPTCStubBase5Stub" #n "Ev\n\t"*/ \ + ".elseif " #n " < 100\n\t" \ + /*".size __ZN14nsXPTCStubBase6Stub" #n "Ev,.-__ZN14nsXPTCStubBase6Stub" #n "Ev\n\t"*/ \ + ".else\n\t" \ + /*".size __ZN14nsXPTCStubBase7Stub" #n "Ev,.-__ZN14nsXPTCStubBase7Stub" #n "Ev\n\t"*/ \ + ".endif"); + +// static nsresult SharedStub(PRUint32 methodIndex) [methodIndex is in eax]. +asm(".text\n\t" + ".align 2\n\t" +/* ".type SharedStub,@function\n\t" */ + "SharedStub:\n\t" + // make room for gpregs (48), fpregs (64) + "pushq %rbp\n\t" + "movq %rsp,%rbp\n\t" + "subq $112,%rsp\n\t" + // save GP registers + "movq %rdi,-112(%rbp)\n\t" + "movq %rsi,-104(%rbp)\n\t" + "movq %rdx, -96(%rbp)\n\t" + "movq %rcx, -88(%rbp)\n\t" + "movq %r8 , -80(%rbp)\n\t" + "movq %r9 , -72(%rbp)\n\t" + "leaq -112(%rbp),%rcx\n\t" + // save FP registers + "movsd %xmm0,-64(%rbp)\n\t" + "movsd %xmm1,-56(%rbp)\n\t" + "movsd %xmm2,-48(%rbp)\n\t" + "movsd %xmm3,-40(%rbp)\n\t" + "movsd %xmm4,-32(%rbp)\n\t" + "movsd %xmm5,-24(%rbp)\n\t" + "movsd %xmm6,-16(%rbp)\n\t" + "movsd %xmm7, -8(%rbp)\n\t" + "leaq -64(%rbp),%r8\n\t" + // rdi has the 'self' pointer already + "movl %eax,%esi\n\t" + "leaq 16(%rbp),%rdx\n\t" + "call _PrepareAndDispatch\n\t" + "leave\n\t" + "ret\n\t" +/* ".size SharedStub,.-SharedStub" */ + ); + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#else +#error "Unsupported compiler. Use gcc >= 3.1 for Darwin/AMD64." +#endif /* __GNUC__ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp new file mode 100644 index 00000000..fc90ecea --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp @@ -0,0 +1,244 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Russell King <rmk@arm.linux.org.uk> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if !defined(LINUX) || !defined(__arm__) +#error "This code is for Linux ARM only. Please check if it works for you, too.\nDepends strongly on gcc behaviour." +#endif + +/* Specify explicitly a symbol for this function, don't try to guess the c++ mangled symbol. */ +static nsresult PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args) asm("_PrepareAndDispatch"); + +static nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args) +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* 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 = *((PRInt8*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt16*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) ap); break; + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U8 : dp->val.u8 = *((PRUint8*) ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint16*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)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 = *((PRBool*) 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_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +/* + * This is our shared stub. + * + * r0 = Self. + * + * The Rules: + * We pass an (undefined) number of arguments into this function. + * The first 3 C++ arguments are in r1 - r3, the rest are built + * by the calling function on the stack. + * + * We are allowed to corrupt r0 - r3, ip, and lr. + * + * Other Info: + * We pass the stub number in using `ip'. + * + * Implementation: + * - We save r1 to r3 inclusive onto the stack, which will be + * immediately below the caller saved arguments. + * - setup r2 (PrepareAndDispatch's args pointer) to point at + * the base of all these arguments + * - Save LR (for the return address) + * - Set r1 (PrepareAndDispatch's methodindex argument) from ip + * - r0 is passed through (self) + * - Call PrepareAndDispatch + * - When the call returns, we return by loading the PC off the + * stack, and undoing the stack (one instruction)! + * + */ +__asm__ ("\n\ +SharedStub: \n\ + stmfd sp!, {r1, r2, r3} \n\ + mov r2, sp \n\ + str lr, [sp, #-4]! \n\ + mov r1, ip \n\ + bl _PrepareAndDispatch \n\ + ldr pc, [sp], #16"); + +/* + * Create sets of stubs to call the SharedStub. + * We don't touch the stack here, nor any registers, other than IP. + * IP is defined to be corruptable by a called function, so we are + * safe to use it. + * + * This will work with or without optimisation. + */ +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ +/* + * Note : As G++3 ABI contains the length of the functionname in the + * mangled name, it is difficult to get a generic assembler mechanism like + * in the G++ 2.95 case. + * Create names would be like : + * _ZN14nsXPTCStubBase5Stub9Ev + * _ZN14nsXPTCStubBase6Stub13Ev + * _ZN14nsXPTCStubBase7Stub144Ev + * Use the assembler directives to get the names right... + */ + +#define STUB_ENTRY(n) \ + __asm__( \ + ".section \".text\"\n" \ +" .align 2\n" \ +" .iflt ("#n" - 10)\n" \ +" .globl _ZN14nsXPTCStubBase5Stub"#n"Ev\n" \ +" .type _ZN14nsXPTCStubBase5Stub"#n"Ev,#function\n" \ +"_ZN14nsXPTCStubBase5Stub"#n"Ev:\n" \ +" .else\n" \ +" .iflt ("#n" - 100)\n" \ +" .globl _ZN14nsXPTCStubBase6Stub"#n"Ev\n" \ +" .type _ZN14nsXPTCStubBase6Stub"#n"Ev,#function\n" \ +"_ZN14nsXPTCStubBase6Stub"#n"Ev:\n" \ +" .else\n" \ +" .iflt ("#n" - 1000)\n" \ +" .globl _ZN14nsXPTCStubBase7Stub"#n"Ev\n" \ +" .type _ZN14nsXPTCStubBase7Stub"#n"Ev,#function\n" \ +"_ZN14nsXPTCStubBase7Stub"#n"Ev:\n" \ +" .else\n" \ +" .err \"stub number "#n"> 1000 not yet supported\"\n" \ +" .endif\n" \ +" .endif\n" \ +" .endif\n" \ +" mov ip, #"#n"\n" \ +" b SharedStub\n\t"); + +#if 0 +/* + * This part is left in as comment : this is how the method definition + * should look like. + */ + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n () \ +{ \ + __asm__ ( \ +" mov ip, #"#n"\n" \ +" b SharedStub\n\t"); \ + return 0; /* avoid warnings */ \ +} +#endif + +#else /* G++2.95 ABI */ + +#define STUB_ENTRY(n) \ + __asm__( \ + ".section \".text\"\n" \ +" .align\n" \ +" .globl Stub"#n"__14nsXPTCStubBase\n" \ +" .type Stub"#n"__14nsXPTCStubBase,#function\n\n" \ +"Stub"#n"__14nsXPTCStubBase:\n" \ +" mov ip, #"#n"\n" \ +" b SharedStub\n\t"); + +#endif + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm64_vbox.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm64_vbox.cpp new file mode 100644 index 00000000..82856234 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm64_vbox.cpp @@ -0,0 +1,272 @@ +/* $Id: xptcstubs_arm64_vbox.cpp $ */ +/** @file + * XPCOM - XPTC stubs for arm64. + */ + +/* + * Copyright (C) 2021-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "xptcprivate.h" +#include <iprt/cdefs.h> +#include <iprt/alloca.h> +#include <iprt/assert.h> + + +/********************************************************************************************************************************* +* Defined Constants And Macros * +*********************************************************************************************************************************/ +#if defined(RT_OS_DARWIN) +# define NAME_PREFIX _ +# define NAME_PREFIX_STR "_" +#else +# define NAME_PREFIX +# define NAME_PREFIX_STR "" +#endif +#define ASMNAME(a_Name) NAME_PREFIX ## a_Name +#define NUM_ARGS_IN_GPRS 8 /**< Number of arguments passed in general purpose registers (starting with x0). */ +#define NUM_ARGS_IN_FPRS 8 /**< Number of arguments passed in floating point registers (starting with d0). */ + + +/********************************************************************************************************************************* +* Internal Functions * +*********************************************************************************************************************************/ +extern "C" __attribute__((naked)) nsresult CommonXPTCStub(void); +DECL_NO_INLINE(extern "C", nsresult) +CommonXPTCStubCWorker(nsXPTCStubBase *pThis, uint32_t idxMethod, uint64_t *pauGprArgs, uint64_t *pauFprArgs, uint64_t *puStackArgs); + + +/** + * All the stubs call this shared code w/ method index in w17. + * + * The naked attribute means pure inline assembly function. clang complains + * if we put C statements in it. So, this exacty what we need here and for the + * stubs. + * + * @note This could be static if we weren't afraid the compile would optimize it + * out. + */ +extern "C" __attribute__((naked)) nsresult CommonXPTCStub(void) +{ + __asm__ __volatile__( + /* Prologue - reserve space for frame+link reg spill and the GPR and FPR arrays. */ "\ + sub sp, sp, %[cbGPRandFPRs] + 16 \n\ + stp x29, x30, [sp, %[cbGPRandFPRs]] \n\ + add x29, sp, %[cbGPRandFPRs] \n\ + .cfi_def_cfa x29, 16 \n\ + .cfi_rel_offset x30, -8 \n\ + .cfi_rel_offset x29, -16 \n\ +" + /* reserve stack space for the integer and floating point registers and save them: */ "\ + \n\ + stp x0, x1, [sp, #0] \n\ + stp x2, x3, [sp, #16] \n\ + stp x4, x5, [sp, #32] \n\ + stp x6, x7, [sp, #48] \n\ + \n\ + stp d0, d1, [sp, %[cbGPRs]] \n\ + stp d2, d3, [sp, %[cbGPRs] + 16] \n\ + stp d4, d5, [sp, %[cbGPRs] + 32] \n\ + stp d6, d7, [sp, %[cbGPRs] + 48] \n\ +\n" + /* Call the C worker. We keep x0 as is. + Set w1 to the w17 method index from the stubs. */ "\ + mov w1, w17 \n\ + mov x2, sp \n\ + add x3, sp, %[cbGPRs] \n\ + add x4, sp, %[cbGPRandFPRs] + 16 \n\ + bl " NAME_PREFIX_STR "CommonXPTCStubCWorker \n\ +" + /* Epilogue (clang does not emit the .cfi's here, so drop them too?): */ "\ + ldp x29, x30, [sp, %[cbGPRandFPRs]] \n\ + add sp, sp, %[cbGPRandFPRs] + 16 \n\ + .cfi_def_cfa sp, 0 \n\ + .cfi_restore x29 \n\ + .cfi_restore x30 \n\ + ret \n\ +" : + : [cbGPRandFPRs] "i" (NUM_ARGS_IN_GPRS * 8 + NUM_ARGS_IN_FPRS * 8) + , [cbGPRs] "i" (NUM_ARGS_IN_GPRS * 8) + :); +} + +#define STUB_ENTRY(n) \ + __attribute__((naked)) nsresult nsXPTCStubBase::Stub##n() \ + { \ + __asm__ __volatile__ ("mov w17, #" #n "\n\t" \ + "b " NAME_PREFIX_STR "CommonXPTCStub\n\t"); \ + } + +#define SENTINEL_ENTRY(n) \ + nsresult nsXPTCStubBase::Sentinel##n() \ + { \ + AssertMsgFailed(("nsXPTCStubBase::Sentinel" #n " called!\n")); \ + return NS_ERROR_NOT_IMPLEMENTED; \ + } + +/* Instantiate the stubs and sentinels */ +#include "xptcstubsdef.inc" + + + +/* + * Function templates for fetching arguments + */ + +template<typename Type> static inline void fetchStack(Type *pRet, uint64_t *&rpuStackArgs) +{ +#ifdef RT_OS_DARWIN /* macOS compacts stack usage. */ + Type *pStackTmp = RT_ALIGN_PT(rpuStackArgs, sizeof(Type), Type *); + *pRet = *pStackTmp; + rpuStackArgs = (uint64_t *)(pStackTmp + 1); +#else + *pRet = (Type)*rpuStackArgs++; +#endif +} + +template<typename Type> static inline void fetchFpr(Type *pRet, uint64_t *pauFprArgs, unsigned &ridxFpr, uint64_t *&rpuStackArgs) +{ + if (ridxFpr < NUM_ARGS_IN_FPRS) + *pRet = (Type)pauFprArgs[ridxFpr++]; + else + fetchStack(pRet, rpuStackArgs); +} + + +template<typename Type> static inline void fetchGpr(Type *pRet, uint64_t *pauGprArgs, unsigned &ridxGpr, uint64_t *&rpuStackArgs) +{ + if (ridxGpr < NUM_ARGS_IN_GPRS) + *pRet = (Type)pauGprArgs[ridxGpr++]; + else + fetchStack(pRet, rpuStackArgs); +} + + +/** + * Called by CommonXPTCStub below after it dumps registers and locates + * arguments on the stack (if any). + */ +DECL_NO_INLINE(extern "C", nsresult) +CommonXPTCStubCWorker(nsXPTCStubBase *pThis, uint32_t idxMethod, uint64_t *pauGprArgs, uint64_t *pauFprArgs, uint64_t *puStackArgs) +{ + AssertReturn(pThis, NS_ERROR_UNEXPECTED); + + /* Get method information: */ + nsIInterfaceInfo *pInterfaceInfo = NULL; + nsresult hrc = pThis->GetInterfaceInfo(&pInterfaceInfo); + AssertReturn(NS_SUCCEEDED(hrc), hrc); + AssertReturn(pInterfaceInfo, NS_ERROR_UNEXPECTED); + + const nsXPTMethodInfo *pMethodInfo; + hrc = pInterfaceInfo->GetMethodInfo((PRUint16)idxMethod, &pMethodInfo); + AssertReturn(NS_SUCCEEDED(hrc), hrc); + AssertReturn(pMethodInfo, NS_ERROR_UNEXPECTED); + + /* Allocate dispatcher parameter array. */ + PRUint8 const cParams = pMethodInfo->GetParamCount(); + nsXPTCMiniVariant aParamsStatic[8]; + nsXPTCMiniVariant *paParams; + if (cParams <= RT_ELEMENTS(aParamsStatic)) + paParams = aParamsStatic; + else + { + paParams = (nsXPTCMiniVariant *)alloca(sizeof(paParams[0]) * cParams); + AssertReturn(paParams, NS_ERROR_UNEXPECTED); + } + + /* + * Populate the dispatcher parameter array. + */ + unsigned idxGprArgs = 1; /* The 'pThis' pointer (x0) is not included in cParams. */ + unsigned idxFprArgs = 0; + for (PRUint8 i = 0; i < cParams; i++) + { + const nsXPTParamInfo &rParam = pMethodInfo->GetParam(i); + if (rParam.IsOut()) + fetchGpr(&paParams[i].val.p, pauGprArgs, idxGprArgs, puStackArgs); + else + { + const nsXPTType Type = rParam.GetType(); + switch (Type) + { + case nsXPTType::T_I8: fetchGpr(&paParams[i].val.i8, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_I16: fetchGpr(&paParams[i].val.i16, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_I32: fetchGpr(&paParams[i].val.i32, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_I64: fetchGpr(&paParams[i].val.i64, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_U8: fetchGpr(&paParams[i].val.u8, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_U16: fetchGpr(&paParams[i].val.u16, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_U32: fetchGpr(&paParams[i].val.u32, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_U64: fetchGpr(&paParams[i].val.u64, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_BOOL: fetchGpr(&paParams[i].val.b, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_CHAR: fetchGpr(&paParams[i].val.c, pauGprArgs, idxGprArgs, puStackArgs); break; + case nsXPTType::T_WCHAR: fetchGpr(&paParams[i].val.wc, pauGprArgs, idxGprArgs, puStackArgs); break; + + case nsXPTType::T_FLOAT: fetchFpr(&paParams[i].val.f, pauFprArgs, idxFprArgs, puStackArgs); break; + case nsXPTType::T_DOUBLE: fetchFpr(&paParams[i].val.d, pauFprArgs, idxFprArgs, puStackArgs); break; + + default: + if (!Type.IsArithmetic()) + fetchGpr(&paParams[i].val.p, pauGprArgs, idxGprArgs, puStackArgs); + else + AssertMsgFailedReturn(("%#x idxMethod=%#x\n",(unsigned)Type, idxMethod), NS_ERROR_UNEXPECTED); + break; + } + } + } + + /* + * Dispatch the method call. + */ + hrc = pThis->CallMethod((PRUint16)idxMethod, pMethodInfo, paParams); + + NS_RELEASE(pInterfaceInfo); + return hrc; + +} + +#if 0 +extern "C" nsresult CommonXPTCStubTest(uint64_t x0, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + uint64_t x5, + uint64_t x6, + uint64_t x7) +{ + uint64_t aGprs[8]; + aGprs[0] = x0; + aGprs[1] = x1; + aGprs[2] = x2; + aGprs[3] = x3; + aGprs[4] = x4; + aGprs[5] = x5; + aGprs[6] = x6; + aGprs[7] = x7; + + return CommonXPTCStubCWorker((nsXPTCStubBase *)x0, x1, aGprs, aGprs, aGprs); +} +#endif + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm_netbsd.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm_netbsd.cpp new file mode 100644 index 00000000..47c09a42 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm_netbsd.cpp @@ -0,0 +1,145 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args) +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* 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 = *((PRInt8*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt16*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) ap); break; + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U8 : dp->val.u8 = *((PRUint8*) ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint16*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)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 = *((PRBool*) 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_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +/* + * These stubs move just move the values passed in registers onto the stack, + * so they are contiguous with values passed on the stack, and then calls + * PrepareAndDispatch() to do the dirty work. + */ + +#define STUB_ENTRY(n) \ +__asm__( \ + ".global _Stub"#n"__14nsXPTCStubBase\n\t" \ +"_Stub"#n"__14nsXPTCStubBase:\n\t" \ + "stmfd sp!, {r1, r2, r3} \n\t" \ + "mov ip, sp \n\t" \ + "stmfd sp!, {fp, ip, lr, pc} \n\t" \ + "sub fp, ip, #4 \n\t" \ + "mov r1, #"#n" \n\t" /* = methodIndex */ \ + "add r2, sp, #16 \n\t" \ + "bl _PrepareAndDispatch__FP14nsXPTCStubBaseUiPUi \n\t" \ + "ldmea fp, {fp, sp, lr} \n\t" \ + "add sp, sp, #12 \n\t" \ + "mov pc, lr \n\t" \ +); + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf32.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf32.s new file mode 100644 index 00000000..591e88e5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf32.s @@ -0,0 +1,124 @@ + +// Select C numeric constant + .radix C + .psr abi32 + .psr msb +// Section has executable code + .section .text, "ax","progbits" +// procedure named 'SharedStub' + .proc SharedStub +// manual bundling + .explicit + + .global PrepareAndDispatch +// .exclass PrepareAndDispatch, @fullyvisible + .type PrepareAndDispatch,@function + +SharedStub:: +// 9 arguments, first 8 are the input arguments of previous +// function call. The last one is methodIndex, and is passed in memory + .prologue + .save ar.pfs , r41 +// allocate 8 input args, 4 local args, and 5 output args + alloc r41 = ar.pfs, 8, 4, 5, 0 // M + .save rp, r40 + mov r40 = rp // I + nop.i 0 ;; // I + + .save ar.unat, r42 + mov r42 = ar.unat // M + .fframe 144 + add sp = -144, sp // A +// unwind table already knows gp, don't need to specify anything + add r43 = 0, gp ;; // A + +// We have possible 8 integer registers and 8 float registers that could +// be arguments. We also have a stack region from the previous +// stack frame that may hold some stack arguments. +// We need to write the integer registers to a memory region, write +// the float registers to a memory region (making sure we don't step +// on NAT while touching the registers). We also mark the memory +// address of the stack arguments. +// We then call PrepareAndDispatch() specifying the three memory +// region pointers. + + + .body + add out0 = 0, in0 // A move self ptr +// 144 bytes = 16 byte stack header + 64 byte int space + 64 byte float space +// current frame is 144 bytes, previous frame is 112 bytes +// restarg is at 144 + 112 + 16 bytes away from current sp +// (current frame + previous frame + previous previous frame header) +// methodIndex is at 144 + 16 bytes away from current sp +// (current frame + previous frame header) + add out4 = 192, sp // A restarg address + add r11 = 160, sp ;; // A address of methodIndex + + ld8 out1 = [r11] // M load methodIndex +// sp + 16 is the start of intargs + add out2 = 16, sp // A address of intargs +// the intargs take up 64 bytes, so sp + 16 + 64 is the start of floatargs + add out3 = 80, sp ;; // A address of floatargs + + add r11 = 0, out2 ;; // A + st8.spill [r11] = in1, 8 // M + add r10 = 0, out3 ;; // A + + st8.spill [r11] = in2, 8 ;; // M + st8.spill [r11] = in3, 8 // M + nop.i 0 ;; // I + + st8.spill [r11] = in4, 8 ;; // M + st8.spill [r11] = in5, 8 // M + nop.i 0 ;; // I + + st8.spill [r11] = in6, 8 ;; // M + st8.spill [r11] = in7 // M + fclass.nm p14,p15 = f8,@nat ;; // F + +(p14) stfd [r10] = f8, 8 // M +(p15) add r10 = 8, r10 // A + fclass.nm p12,p13 = f9,@nat ;; // F + +(p12) stfd [r10] = f9, 8 // M +(p13) add r10 = 8, r10 // A + fclass.nm p14,p15 =f10,@nat ;; // F + +(p14) stfd [r10] = f10, 8 // M +(p15) add r10 = 8, r10 // A + fclass.nm p12,p13 =f11,@nat ;; // F + +(p12) stfd [r10] = f11, 8 // M +(p13) add r10 = 8, r10 // A + fclass.nm p14,p15 =f12,@nat ;; // F + +(p14) stfd [r10] = f12, 8 // M +(p15) add r10 = 8, r10 // A + fclass.nm p12,p13 =f13,@nat ;; // F + +(p12) stfd [r10] = f13, 8 // M +(p13) add r10 = 8, r10 // A + fclass.nm p14,p15 =f14,@nat ;; // F + +(p14) stfd [r10] = f14, 8 // M +(p15) add r10 = 8, r10 // A + fclass.nm p12,p13 =f15,@nat ;; // F + +(p12) stfd [r10] = f15, 8 // M +(p13) add r10 = 8, r10 // A + +// branch to PrepareAndDispatch + br.call.dptk.few rp = PrepareAndDispatch ;; // B + +// epilog + mov ar.unat = r42 // M + mov ar.pfs = r41 // I + mov rp = r40 ;; // I + + add gp = 0, r43 // A + add sp = 144, sp // A + br.ret.dptk.few rp ;; // B + + .endp + + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf64.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf64.s new file mode 100644 index 00000000..177b2646 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf64.s @@ -0,0 +1,124 @@ + +// Select C numeric constant + .radix C + .psr abi64 + .psr lsb +// Section has executable code + .section .text, "ax","progbits" +// procedure named 'SharedStub' + .proc SharedStub +// manual bundling + .explicit + + .global PrepareAndDispatch +// .exclass PrepareAndDispatch, @fullyvisible + .type PrepareAndDispatch,@function + +SharedStub:: +// 9 arguments, first 8 are the input arguments of previous +// function call. The last one is methodIndex, and is passed in memory + .prologue + .save ar.pfs , r41 +// allocate 8 input args, 4 local args, and 5 output args + alloc r41 = ar.pfs, 8, 4, 5, 0 // M + .save rp, r40 + mov r40 = rp // I + nop.i 0 ;; // I + + .save ar.unat, r42 + mov r42 = ar.unat // M + .fframe 144 + add sp = -144, sp // A +// unwind table already knows gp, don't need to specify anything + add r43 = 0, gp ;; // A + +// We have possible 8 integer registers and 8 float registers that could +// be arguments. We also have a stack region from the previous +// stack frame that may hold some stack arguments. +// We need to write the integer registers to a memory region, write +// the float registers to a memory region (making sure we don't step +// on NAT while touching the registers). We also mark the memory +// address of the stack arguments. +// We then call PrepareAndDispatch() specifying the three memory +// region pointers. + + + .body + add out0 = 0, in0 // A move self ptr +// 144 bytes = 16 byte stack header + 64 byte int space + 64 byte float space +// current frame is 144 bytes, previous frame is 112 bytes +// restarg is at 144 + 112 + 16 bytes away from current sp +// (current frame + previous frame + previous previous frame header) +// methodIndex is at 144 + 16 bytes away from current sp +// (current frame + previous frame header) + add out4 = 192, sp // A restarg address + add r11 = 160, sp ;; // A address of methodIndex + + ld8 out1 = [r11] // M load methodIndex +// sp + 16 is the start of intargs + add out2 = 16, sp // A address of intargs +// the intargs take up 64 bytes, so sp + 16 + 64 is the start of floatargs + add out3 = 80, sp ;; // A address of floatargs + + add r11 = 0, out2 ;; // A + st8.spill [r11] = in1, 8 // M + add r10 = 0, out3 ;; // A + + st8.spill [r11] = in2, 8 ;; // M + st8.spill [r11] = in3, 8 // M + nop.i 0 ;; // I + + st8.spill [r11] = in4, 8 ;; // M + st8.spill [r11] = in5, 8 // M + nop.i 0 ;; // I + + st8.spill [r11] = in6, 8 ;; // M + st8.spill [r11] = in7 // M + fclass.nm p14,p15 = f8,@nat ;; // F + +(p14) stfd [r10] = f8, 8 // M +(p15) add r10 = 8, r10 // A + fclass.nm p12,p13 = f9,@nat ;; // F + +(p12) stfd [r10] = f9, 8 // M +(p13) add r10 = 8, r10 // A + fclass.nm p14,p15 =f10,@nat ;; // F + +(p14) stfd [r10] = f10, 8 // M +(p15) add r10 = 8, r10 // A + fclass.nm p12,p13 =f11,@nat ;; // F + +(p12) stfd [r10] = f11, 8 // M +(p13) add r10 = 8, r10 // A + fclass.nm p14,p15 =f12,@nat ;; // F + +(p14) stfd [r10] = f12, 8 // M +(p15) add r10 = 8, r10 // A + fclass.nm p12,p13 =f13,@nat ;; // F + +(p12) stfd [r10] = f13, 8 // M +(p13) add r10 = 8, r10 // A + fclass.nm p14,p15 =f14,@nat ;; // F + +(p14) stfd [r10] = f14, 8 // M +(p15) add r10 = 8, r10 // A + fclass.nm p12,p13 =f15,@nat ;; // F + +(p12) stfd [r10] = f15, 8 // M +(p13) add r10 = 8, r10 // A + +// branch to PrepareAndDispatch + br.call.dptk.few rp = PrepareAndDispatch ;; // B + +// epilog + mov ar.unat = r42 // M + mov ar.pfs = r41 // I + mov rp = r40 ;; // I + + add gp = 0, r43 // A + add sp = 144, sp // A + br.ret.dptk.few rp ;; // B + + .endp + + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_irix.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_irix.s new file mode 100644 index 00000000..4ca1e542 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_irix.s @@ -0,0 +1,97 @@ + +#include <sys/regdef.h> +#include <sys/asm.h> + + .text + .globl PrepareAndDispatch + +LOCALSZ=16 +FRAMESZ=(((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK + +A1OFF=FRAMESZ-(9*SZREG) +A2OFF=FRAMESZ-(8*SZREG) +A3OFF=FRAMESZ-(7*SZREG) +A4OFF=FRAMESZ-(6*SZREG) +A5OFF=FRAMESZ-(5*SZREG) +A6OFF=FRAMESZ-(4*SZREG) +A7OFF=FRAMESZ-(3*SZREG) +GPOFF=FRAMESZ-(2*SZREG) +RAOFF=FRAMESZ-(1*SZREG) + +F13OFF=FRAMESZ-(16*SZREG) +F14OFF=FRAMESZ-(15*SZREG) +F15OFF=FRAMESZ-(14*SZREG) +F16OFF=FRAMESZ-(13*SZREG) +F17OFF=FRAMESZ-(12*SZREG) +F18OFF=FRAMESZ-(11*SZREG) +F19OFF=FRAMESZ-(10*SZREG) + +#define SENTINEL_ENTRY(nn) /* defined in cpp file, not here */ + +#ifdef __GNUC__ +#define STUB_ENTRY(nn) MAKE_STUB(nn, Stub/**/nn/**/__14nsXPTCStubBase) +#else +#define STUB_ENTRY(nn) MAKE_STUB(nn, Stub/**/nn/**/__14nsXPTCStubBaseGv) +#endif + +#define MAKE_STUB(nn, name) \ +NESTED(name, FRAMESZ, ra); \ + SETUP_GP; \ + PTR_SUBU sp, FRAMESZ; \ + SETUP_GP64(GPOFF, name); \ + SAVE_GP(GPOFF); \ + li t0, nn; \ + b sharedstub; \ +.end name; \ + +#include "xptcstubsdef.inc" + + .globl sharedstub + .ent sharedstub +sharedstub: + + REG_S a1, A1OFF(sp) + REG_S a2, A2OFF(sp) + REG_S a3, A3OFF(sp) + REG_S a4, A4OFF(sp) + REG_S a5, A5OFF(sp) + REG_S a6, A6OFF(sp) + REG_S a7, A7OFF(sp) + REG_S ra, RAOFF(sp) + + s.d $f13, F13OFF(sp) + s.d $f14, F14OFF(sp) + s.d $f15, F15OFF(sp) + s.d $f16, F16OFF(sp) + s.d $f17, F17OFF(sp) + s.d $f18, F18OFF(sp) + s.d $f19, F19OFF(sp) + + # t0 is methodIndex + move a1, t0 + + # a2 is stack address where extra function params + # are stored that do not fit in registers + move a2, sp + addi a2, FRAMESZ + + # a3 is stack address of a1..a7 + move a3, sp + addi a3, A1OFF + + # a4 is stack address of f13..f19 + move a4, sp + addi a4, F13OFF + + # PrepareAndDispatch(that, methodIndex, args, gprArgs, fpArgs) + # a0 a1 a2 a3 a4 + # + jal PrepareAndDispatch + + REG_L ra, RAOFF(sp) + REG_L gp, GPOFF(sp) + + PTR_ADDU sp, FRAMESZ + j ra + +.end sharedstub diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s.m4 b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s.m4 new file mode 100644 index 00000000..f327adfb --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s.m4 @@ -0,0 +1,109 @@ +/* -*- Mode: asm; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * Version: MPL 1.1 + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp, Inc. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> + * Chris Waterson <waterson@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* This code is for MIPS using the O32 ABI. */ + +#include <sys/regdef.h> +#include <sys/asm.h> + + .text + .globl PrepareAndDispatch + +NARGSAVE=4 # extra space for the callee to use. gccism + # we can put our a0-a3 in our callers space. +LOCALSZ=2 # gp, ra +FRAMESZ=(((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK + +define(STUB_NAME, `Stub'$1`__14nsXPTCStubBase') + +define(STUB_ENTRY, +` .globl 'STUB_NAME($1)` + .align 2 + .type 'STUB_NAME($1)`,@function + .ent 'STUB_NAME($1)`, 0 +'STUB_NAME($1)`: + .frame sp, FRAMESZ, ra + .set noreorder + .cpload t9 + .set reorder + subu sp, FRAMESZ + .cprestore 16 + li t0, '$1` + b sharedstub +.end 'STUB_NAME($1)` + +') + +define(SENTINEL_ENTRY, `') + +include(xptcstubsdef.inc) + + .globl sharedstub + .ent sharedstub +sharedstub: + + REG_S ra, 20(sp) + + REG_S a0, 24(sp) + REG_S a1, 28(sp) + REG_S a2, 32(sp) + REG_S a3, 36(sp) + + # t0 is methodIndex + move a1, t0 + + # put the start of a1, a2, a3, and stack + move a2, sp + addi a2, 24 # have a2 point to sp + 24 (where a0 is) + + # PrepareAndDispatch(that, methodIndex, args) + # a0 a1 a2 + # + jal PrepareAndDispatch + + REG_L ra, 20(sp) + REG_L a1, 28(sp) + REG_L a2, 32(sp) + + addu sp, FRAMESZ + j ra + +.end sharedstub diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_openvms_alpha.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_openvms_alpha.s new file mode 100644 index 00000000..9f04d4c4 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_openvms_alpha.s @@ -0,0 +1,115 @@ +;* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +;* +;* The contents of this file are subject to the Netscape Public +;* License Version 1.1 (the "License"); you may not use this file +;* except in compliance with the License. You may obtain a copy of +;* the License at http://www.mozilla.org/NPL/ +;* +;* Software distributed under the License is distributed on an "AS +;* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +;* implied. See the License for the specific language governing +;* rights and limitations under the License. +;* +;* The Original Code is mozilla.org code. +;* +;* The Initial Developer of the Original Code is Netscape +;* Communications Corporation. Portions created by Netscape are +;* Copyright (C) 1999 Netscape Communications Corporation. All +;* Rights Reserved. +;* +;* Contributor(s): +;*/ + +; Implement shared vtbl methods. + + .title "STUBS" "Stub Code" + + MBIT = "__14nsXPTCStubBasexv" ; this is the mangled part of the name + +; The layout of the linkage section is important. First comes +; PrepareAndDispatch, and then the Procedure Descriptors for the stubs. Each +; is known to be 16 bytes long, and we use this fact to be able to locate the +; PrepareAndDispatch linkage pair from any of the stubs. + + .PSECT $LINK$, OCTA, NOPIC, CON, REL, LCL, NOSHR, NOEXE, RD, NOWRT + .LINKAGE_PAIR PrepareAndDispatch + LINKOFF = 16 ; first stub lp will be 16 bytes away + +; STUB_ENTRY createa a routine nsXPTCStubBase::Stub<n>() where n is the +; argument passed in to STUB_ENTRY. It puts its stub number into R1 and then +; jumps into SharedStub. It does it this way because we don't want to mess +; up the arguments that may be on the stack. In order that we can find +; our way around the linkage section, we subtract our offset from the +; start of the linkage section (LINKOFF) from our own PV, thus giving +; us the PV os the first entry in the linkage section (this should be +; PrepareAndDispatch); + + .macro STUB_ENTRY n + $routine Stub'n%MBIT%, kind=null + mov LINKOFF, r1 ; distance from lp for PrepareAndDispatch + subq r27,r1,r27 ; subtract it from address of our proc desc + mov n,r1 ; stub number is passed in r1 + br SharedStub ; off to common code + $end_routine + LINKOFF = LINKOFF + 16 ; we just put 16 bytes into linkage section + .endm STUB_ENTRY + +; SENTINEL_ENTRY is in the C++ module. We need to define a empty macro +; here to keep the assembler happy. + .macro SENTINEL_ENTRY n + .endm SENTINEL_ENTRY + + .PSECT $CODE$, OCTA, PIC, CON, REL, LCL, SHR, EXE, NORD, NOWRT + +; +; SharedStub() +; Collects arguments and calls PrepareAndDispatch. +; +; r1 - The "methodIndex" +; r27 - points to the first entry in the linkage section, which by design +; is the linkage pair for PrepareAndDispatch. +; +; Arguments are passed in a non-standard way so that we don't disturb the +; original arguments that were passed in to the stub. Since some args (if +; there were more than 6) will already be on the stack, the stub had to not +; only preserve R16-R21, but also preserve the stack too. +; + +SharedStub:: + subq sp,96,sp ; get some stack space for the args and saves + stq r26,0(sp) ; save r26 (the return address) + + ; + ; Store arguments passed via registers to the stack. + ; Floating point registers are stored as doubles and converted + ; to floats in PrepareAndDispatch if necessary. + ; + stt f17,16(sp) ; floating point registers + stt f18,24(sp) + stt f19,32(sp) + stt f20,40(sp) + stt f21,48(sp) + stq r17,56(sp) ; integer registers + stq r18,64(sp) + stq r19,72(sp) + stq r20,80(sp) + stq r21,88(sp) + + ; + ; Call PrepareAndDispatch function. + ; + mov r1,r17 ; pass "methodIndex" + addq sp,16,r18 ; pass "args" + mov 3,r25 ; number of args into AI + + LDQ R26, 0(R27) ; get entry point address from linkage pair + LDQ R27, 8(R27) ; get procedure descriptor address from lp + JSR R26, R26 + + ldq r26, 0(sp) ; restore return address + addq sp,96,sp ; return stack space + ret r26 ; and we're outta here + + .include "xptcstubsdef_asm.vms" + + .end diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_osf1_alpha.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_osf1_alpha.s new file mode 100644 index 00000000..3bef9b1b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_osf1_alpha.s @@ -0,0 +1,75 @@ + .text + .align 5 + .globl SharedStub + .ent SharedStub +SharedStub: + .frame $30, 96, $26, 0 + .mask 0x4000000,-96 + ldgp $29,0($27) +SharedStubXv: + subq $30,96,$30 + stq $26,0($30) + .prologue 1 + stt $f17,16($30) + stt $f18,24($30) + stt $f19,32($30) + stt $f20,40($30) + stt $f21,48($30) + stq $17,56($30) + stq $18,64($30) + stq $19,72($30) + stq $20,80($30) + stq $21,88($30) + bis $1,$1,$17 + addq $30,16,$18 + bsr $26,PrepareAndDispatch + ldq $26,0($30) + addq $30,96,$30 + ret $31,($26),1 + .end SharedStub + +/* + The C preprocessor doesn't handle # and ## if run with -std or -std0. + + If -std then __STDC__ is 0 [default] (K&R behavior) + If -std0 then __STDC__ is undefined (K&R behavior) + If -std1 then __STDC__ is 1 (ANSI preprocessor) +*/ + +#if __STDC__ +#define STUB_ENTRY(n) ;\ + .text ;\ + .align 5 ;\ + .globl Stub##n##__14nsXPTCStubBase ;\ + .globl Stub##n##__14nsXPTCStubBaseXv ;\ + .ent Stub##n##__14nsXPTCStubBase ;\ +Stub##n##__14nsXPTCStubBase: ;\ + .frame $30,0,$26,0 ;\ + ldgp $29,0($27) ;\ + .prologue 1 ;\ +Stub##n##__14nsXPTCStubBaseXv: ;\ + lda $1,n ;\ + br $31,SharedStubXv ;\ + .end Stub##n##__14nsXPTCStubBase \ + +#else +#define STUB_ENTRY(n) ;\ + .text ;\ + .align 5 ;\ + .globl Stub/**/n/**/__14nsXPTCStubBase ;\ + .globl Stub/**/n/**/__14nsXPTCStubBaseXv ;\ + .ent Stub/**/n/**/__14nsXPTCStubBase ;\ +Stub/**/n/**/__14nsXPTCStubBase: ;\ + .frame $30,0,$26,0 ;\ + ldgp $29,0($27) ;\ + .prologue 1 ;\ +Stub/**/n/**/__14nsXPTCStubBaseXv: ;\ + lda $1,n ;\ + br $31,SharedStubXv ;\ + .end Stub/**/n/**/__14nsXPTCStubBase \ + +#endif + +#define SENTINEL_ENTRY(n) \ + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_pa32.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_pa32.s new file mode 100644 index 00000000..9e86848f --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_pa32.s @@ -0,0 +1,68 @@ + .LEVEL 1.1 + +curframesz .EQU 128 +; SharedStub has stack size of 128 bytes + +lastframesz .EQU 64 +; the StubN C++ function has a small stack size of 64 bytes + + .SPACE $TEXT$,SORT=8 + .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24 +SharedStub + .PROC + .CALLINFO CALLER,FRAME=80,SAVE_RP,ARGS_SAVED + + .ENTRY + STW %rp,-20(%sp) + LDO 128(%sp),%sp + + STW %r19,-32(%r30) + STW %r26,-36-curframesz(%r30) ; save arg0 in previous frame + + LDO -80(%r30),%r28 + FSTD,MA %fr5,8(%r28) ; save darg0 + FSTD,MA %fr7,8(%r28) ; save darg1 + FSTW,MA %fr4L,4(%r28) ; save farg0 + FSTW,MA %fr5L,4(%r28) ; save farg1 + FSTW,MA %fr6L,4(%r28) ; save farg2 + FSTW,MA %fr7L,4(%r28) ; save farg3 + + ; Former value of register 26 is already properly saved by StubN, + ; but register 25-23 are not because of the arguments mismatch + STW %r25,-40-curframesz-lastframesz(%r30) ; save r25 + STW %r24,-44-curframesz-lastframesz(%r30) ; save r24 + STW %r23,-48-curframesz-lastframesz(%r30) ; save r23 + COPY %r26,%r25 ; method index is arg1 + LDW -36-curframesz-lastframesz(%r30),%r26 ; self is arg0 + LDO -40-curframesz-lastframesz(%r30),%r24 ; normal args is arg2 + LDO -80(%r30),%r23 ; floating args is arg3 + + BL .+8,%r2 + ADDIL L'PrepareAndDispatch-$PIC_pcrel$0+4,%r2 + LDO R'PrepareAndDispatch-$PIC_pcrel$1+8(%r1),%r1 +$PIC_pcrel$0 + LDSID (%r1),%r31 +$PIC_pcrel$1 + MTSP %r31,%sr0 + .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR +;in=23-26;out=28; + BLE 0(%sr0,%r1) + COPY %r31,%r2 + + LDW -32(%r30),%r19 + + LDW -148(%sp),%rp + BVE (%rp) + .EXIT + LDO -128(%sp),%sp + + + .PROCEND ;in=26;out=28; + + .ALIGN 8 + .SPACE $TEXT$ + .SUBSPA $CODE$ + .IMPORT PrepareAndDispatch,CODE + .EXPORT SharedStub,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR,LONG_RETURN + .END + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix.s new file mode 100644 index 00000000..667da705 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix.s @@ -0,0 +1,117 @@ + # + # -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + # + # The contents of this file are subject to the Netscape Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/NPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is mozilla.org code. + # + # The Initial Developer of the Original Code is Netscape + # Communications Corporation. Portions created by Netscape are + # Copyright (C) 1999 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): + # + +.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 + + + + .rename H.10.NO_SYMBOL{PR},"" + .rename H.18.SharedStub{TC},"SharedStub" + + +# .text section + + .csect H.10.NO_SYMBOL{PR} + .globl .SharedStub + .globl SharedStub{DS} + .extern .PrepareAndDispatch + + +#jimbo csect CODE{PR} +# +# on entry SharedStub has the method selector in r12, the rest of the original +# parameters are in r3 thru r10 and f1 thru f13 +# +#jimbo import .PrepareAndDispatch + +.SharedStub: + mflr r0 + stw r0,8(sp) + + mr r12,r3 # Move methodIndex into r12 for LATER + lwz r3,104(sp) # Get the 'original' r3 + + stwu sp,-176(sp) # room for linkage (24), fprData (104), gprData(28) + # outgoing params to PrepareAndDispatch (20) + + stw r4,44(sp) + stw r5,48(sp) + stw r6,52(sp) + stw r7,56(sp) + stw r8,60(sp) + stw r9,64(sp) + stw r10,68(sp) + stfd f1,72(sp) + stfd f2,80(sp) + stfd f3,88(sp) + stfd f4,96(sp) + stfd f5,104(sp) + stfd f6,112(sp) + stfd f7,120(sp) + stfd f8,128(sp) + stfd f9,136(sp) + stfd f10,144(sp) + stfd f11,152(sp) + stfd f12,156(sp) + stfd f13,164(sp) + + addi r6,sp,44 # gprData + addi r7,sp,72 # fprData + # r3 has the 'self' pointer already + mr r4,r12 # methodIndex selector (it is now LATER) + addi r5,sp,312 # pointer to callers args area, beyond r3-r10 mapped range + + bl .PrepareAndDispatch + nop + + lwz r0,184(sp) + addi sp,sp,176 + mtlr r0 + blr + +# .data section + + .toc # 0x00000038 +T.18.SharedStub: + .tc H.18.SharedStub{TC},SharedStub{DS} + + .csect SharedStub{DS} + .long .SharedStub # "\0\0\0\0" + .long TOC{TC0} # "\0\0\0008" + .long 0x00000000 # "\0\0\0\0" +# End csect SharedStub{DS} + +# .bss section diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix64.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix64.s new file mode 100644 index 00000000..94245d5e --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix64.s @@ -0,0 +1,137 @@ +# ***** BEGIN LICENSE BLOCK ***** +# +# Version: MPL 1.1/LGPL 2.1/GPL 2.0 +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is IBM Corporation. +# Portions created by IBM are +# Copyright (C) 2002, International Business Machines Corporation. +# All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the LGPL or the GPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 + + + .rename H.10.NO_SYMBOL{PR},"" + .rename H.18.SharedStub{TC},"SharedStub" + + +# .text section + + .csect H.10.NO_SYMBOL{PR} + .globl .SharedStub + .globl SharedStub{DS} + .extern .PrepareAndDispatch + + +#jimbo csect CODE{PR} +# +# on entry SharedStub has the method selector in r12, the rest of the original +# parameters are in r3 thru r10 and f1 thru f13 +# +#jimbo import .PrepareAndDispatch + +.SharedStub: + mflr r0 + std r0,16(sp) + + mr r12,r3 # Move methodIndex into r12 for LATER + ld r3,176(sp) # Get the 'original' r3 (load 'this' into r3) + + stdu sp,-248(sp) # room for linkage (24*2), fprData (104), + # gprData(28*2), outgoing params to + # PrepareAndDispatch (40) + + std r4,88(sp) # link area (48) + PrepareAndDispatch parms (40) + std r5,96(sp) + std r6,104(sp) + std r7,112(sp) + std r8,120(sp) + std r9,128(sp) + std r10,136(sp) + stfd f1,144(sp) + stfd f2,152(sp) + stfd f3,160(sp) + stfd f4,168(sp) + stfd f5,176(sp) + stfd f6,184(sp) + stfd f7,192(sp) + stfd f8,200(sp) + stfd f9,208(sp) + stfd f10,216(sp) + stfd f11,224(sp) + stfd f12,232(sp) + stfd f13,240(sp) + + addi r6,sp,88 # gprData + addi r7,sp,144 # fprData + # r3 has the 'self' pointer already + mr r4,r12 # methodIndex selector (it is now LATER) + addi r5,sp,488 # pointer to callers args area, beyond r3-r10 + # mapped range + # 32bit: 176 (stack-distance) 64bit: 248 (stack-distance) + # 104 (this ptr offset) 176 + # 32 (8*4 for r3-r10) 64 (8*8) + # --- --- + # 312 488 + + bl .PrepareAndDispatch + nop + + ld r0,264(sp) # 248+16 + addi sp,sp,248 + mtlr r0 + blr + +# .data section + + .toc # 0x00000038 +T.18.SharedStub: + .tc H.18.SharedStub{TC},SharedStub{DS} + + .csect SharedStub{DS} + .llong .SharedStub # "\0\0\0\0" + .llong TOC{TC0} # "\0\0\0008" + .llong 0x00000000 # "\0\0\0\0" +# End csect SharedStub{DS} + +# .bss section diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_darwin.s.m4 b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_darwin.s.m4 new file mode 100644 index 00000000..60dbd7c3 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_darwin.s.m4 @@ -0,0 +1,126 @@ +/* -*- Mode: asm; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License") ; you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999-2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + .text + .globl _SharedStub + +define(STUB_MANGLED_ENTRY, +` .globl '$2` + .align 2 +'$2`: + addi r12, 0, '$1` + b _SharedStub +') + +define(STUB_ENTRY, +`#ifdef HAVE_GCC3_ABI + .if '$1` < 10 +STUB_MANGLED_ENTRY('$1`, `__ZN14nsXPTCStubBase5Stub'$1`Ev') + .elseif '$1` < 100 +STUB_MANGLED_ENTRY('$1`, `__ZN14nsXPTCStubBase6Stub'$1`Ev') + .elseif '$1` < 1000 +STUB_MANGLED_ENTRY('$1`, `__ZN14nsXPTCStubBase7Stub'$1`Ev') + .else + .err "Stub'$1` >= 1000 not yet supported." + .endif +#else /* !defined(HAVE_GCC3_ABI) */ +STUB_MANGLED_ENTRY('$1`, `_Stub'$1`__14nsXPTCStubBase') +#endif /* !defined(HAVE_GCC3_ABI) */ +') + +define(SENTINEL_ENTRY, `') + +include(xptcstubsdef.inc) + +_SharedStub: + mflr r0 + stw r0,8(r1) + + stwu r1,-176(r1) + + stw r4,44(r1) + stw r5,48(r1) + stw r6,52(r1) + stw r7,56(r1) + stw r8,60(r1) + stw r9,64(r1) + stw r10,68(r1) + stfd f1,72(r1) + stfd f2,80(r1) + stfd f3,88(r1) + stfd f4,96(r1) + stfd f5,104(r1) + stfd f6,112(r1) + stfd f7,120(r1) + stfd f8,128(r1) + stfd f9,136(r1) + stfd f10,144(r1) + stfd f11,152(r1) + stfd f12,156(r1) + stfd f13,164(r1) + + addi r6,r1,44 + addi r7,r1,72 + + mr r4,r12 + addi r5,r1,232 + + bl L_PrepareAndDispatch$stub + nop + + lwz r0,184(r1) + addi r1,r1,176 + mtlr r0 + blr + +.picsymbol_stub +L_PrepareAndDispatch$stub: + .indirect_symbol _PrepareAndDispatch + mflr r0 + bcl 20,31,L1$pb +L1$pb: + mflr r11 + addis r11,r11,ha16(L1$lz-L1$pb) + mtlr r0 + lwz r12,lo16(L1$lz-L1$pb)(r11) + mtctr r12 + addi r11,r11,lo16(L1$lz-L1$pb) + bctr +.lazy_symbol_pointer +L1$lz: + .indirect_symbol _PrepareAndDispatch + .long dyld_stub_binding_helper diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_linux.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_linux.s new file mode 100644 index 00000000..fc85bdb9 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_linux.s @@ -0,0 +1,89 @@ +// -*- Mode: Asm -*- +// +// The contents of this file are subject to the Netscape Public +// License Version 1.1 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of +// the License at http://www.mozilla.org/NPL/ +// +// Software distributed under the License is distributed on an "AS +// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +// implied. See the License for the specific language governing +// rights and limitations under the License. +// +// The Original Code is mozilla.org code. +// +// The Initial Developer of the Original Code is Netscape +// Communications Corporation. Portions created by Netscape are +// Copyright (C) 1999 Netscape Communications Corporation. All +// Rights Reserved. +// +// Contributor(s): +// Franz.Sirl-kernel@lauterbach.com (Franz Sirl) +// beard@netscape.com (Patrick Beard) +// waterson@netscape.com (Chris Waterson) +// + +.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 + + .section ".text" + .align 2 + .globl SharedStub + .type SharedStub,@function + +SharedStub: + stwu sp,-112(sp) // room for + // linkage (8), + // gprData (32), + // fprData (64), + // stack alignment(8) + mflr r0 + stw r0,116(sp) // save LR backchain + + stw r4,12(sp) // save GP registers + stw r5,16(sp) // (n.b. that we don't save r3 + stw r6,20(sp) // because PrepareAndDispatch() is savvy) + stw r7,24(sp) + stw r8,28(sp) + stw r9,32(sp) + stw r10,36(sp) + + stfd f1,40(sp) // save FP registers + stfd f2,48(sp) + stfd f3,56(sp) + stfd f4,64(sp) + stfd f5,72(sp) + stfd f6,80(sp) + stfd f7,88(sp) + stfd f8,96(sp) + + // r3 has the 'self' pointer already + + mr r4,r11 // r4 <= methodIndex selector, passed + // via r11 in the nsXPTCStubBase::StubXX() call + + addi r5,sp,120 // r5 <= pointer to callers args area, + // beyond r3-r10/f1-f8 mapped range + + addi r6,sp,8 // r6 <= gprData + addi r7,sp,40 // r7 <= fprData + + bl PrepareAndDispatch@local // Go! + + lwz r0,116(sp) // restore LR + mtlr r0 + la sp,112(sp) // clean up the stack + blr + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_netbsd.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_netbsd.s new file mode 100644 index 00000000..f94aac4f --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_netbsd.s @@ -0,0 +1,89 @@ +# -*- Mode: Asm -*- +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1999 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# Franz.Sirl-kernel@lauterbach.com (Franz Sirl) +# beard@netscape.com (Patrick Beard) +# waterson@netscape.com (Chris Waterson) +# + +.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 +.set f30,30; .set f31,31 + + .section ".text" + .align 2 + .globl SharedStub + .type SharedStub,@function + +SharedStub: + stwu sp,-112(sp) # room for + # linkage (8), + # gprData (32), + # fprData (64), + # stack alignment(8) + mflr r0 + stw r0,116(sp) # save LR backchain + + stw r4,12(sp) # save GP registers + stw r5,16(sp) # (n.b. that we don't save r3 + stw r6,20(sp) # because PrepareAndDispatch() is savvy) + stw r7,24(sp) + stw r8,28(sp) + stw r9,32(sp) + stw r10,36(sp) + + stfd f1,40(sp) # save FP registers + stfd f2,48(sp) + stfd f3,56(sp) + stfd f4,64(sp) + stfd f5,72(sp) + stfd f6,80(sp) + stfd f7,88(sp) + stfd f8,96(sp) + + # r3 has the 'self' pointer already + + mr r4,r11 # r4 <= methodIndex selector, passed + # via r11 in the nsXPTCStubBase::StubXX() call + + addi r5,sp,120 # r5 <= pointer to callers args area, + # beyond r3-r10/f1-f8 mapped range + + addi r6,sp,8 # r6 <= gprData + addi r7,sp,40 # r7 <= fprData + + bl PrepareAndDispatch@local # Go! + + lwz r0,116(sp) # restore LR + mtlr r0 + la sp,112(sp) # clean up the stack + blr + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_netbsd.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_netbsd.s new file mode 100644 index 00000000..4a8a4698 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_netbsd.s @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + + .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, PRUint32 index, PRUint32* 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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_solaris.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_solaris.s new file mode 100644 index 00000000..4a8a4698 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_solaris.s @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + + .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, PRUint32 index, PRUint32* 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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparcv9_solaris.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparcv9_solaris.s new file mode 100644 index 00000000..e3bbcf8b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparcv9_solaris.s @@ -0,0 +1,67 @@ +/* -*- Mode: asm; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 2001 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> + */ + + .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, 0x7ff + 136, %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 + stx %i1, [%fp + 0x7ff + 136] + stx %i2, [%fp + 0x7ff + 144] + stx %i3, [%fp + 0x7ff + 152] + stx %i4, [%fp + 0x7ff + 160] + stx %i5, [%fp + 0x7ff + 168] +! now we can build our own stack frame + save %sp,-(128 + 64),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 64 +! our function now appears to have been called +! as SharedStub(nsISupports* that, PRUint32 index, PRUint32* 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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_gcc_x86_unix.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_gcc_x86_unix.cpp new file mode 100644 index 00000000..351ee512 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_gcc_x86_unix.cpp @@ -0,0 +1,202 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#ifdef __GNUC__ /* Gnu Compiler. */ + +#include "xptcprivate.h" +#include "xptc_platforms_unixish_x86.h" +#include "xptc_gcc_x86_unix.h" + +extern "C" { +static nsresult ATTRIBUTE_USED +__attribute__ ((regparm (3))) +PrepareAndDispatch(uint32 methodIndex, nsXPTCStubBase* self, PRUint32* args) +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info = NULL; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + if (!iface_info) + return NS_ERROR_UNEXPECTED; + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no method info"); + if (!info) + return NS_ERROR_UNEXPECTED; + + 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"); + if (!dispatchParams) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32* 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 + dp->val.p = (void*) *ap; + switch(type) + { + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)ap); ap++; break; + case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); ap++; break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} +} // extern "C" + +// NOTE! See xptc_gcc_x86_unix.h for the reason this function exists. +#if (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ == 0)) +PRUint32 +xptc_PrepareAndDispatch_keeper (void) +{ + PRUint32 dummy1; + nsresult ATTRIBUTE_USED __attribute__ ((regparm (3))) (*dummy2) + (uint32, nsXPTCStubBase *, PRUint32*) = PrepareAndDispatch; +// dummy2 references PrepareAndDispatch, now "use" it + __asm__ __volatile__ ( + "" + : "=&a" (dummy1) + : "g" (dummy2) + ); + return dummy1 & 0xF0F00000; +} +#endif + +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ +// gcc3 mangling tends to insert the length of the method name +#define STUB_ENTRY(n) \ +asm(".text\n\t" \ + ".align 2\n\t" \ + ".if " #n " < 10\n\t" \ + ".globl " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev\n\t" \ + ".type " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev,@function\n" \ + SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev:\n\t" \ + ".elseif " #n " < 100\n\t" \ + ".globl " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev\n\t" \ + ".type " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev,@function\n" \ + SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev:\n\t" \ + ".elseif " #n " < 1000\n\t" \ + ".globl " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev\n\t" \ + ".type " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev,@function\n" \ + SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev:\n\t" \ + ".else\n\t" \ + ".err \"stub number " #n " >= 1000 not yet supported\"\n\t" \ + ".endif\n\t" \ + "movl $" #n ", %eax\n\t" \ + "jmp " SYMBOL_UNDERSCORE "SharedStub\n\t" \ + ".if " #n " < 10\n\t" \ + ".size " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev,.-" SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev\n\t" \ + ".elseif " #n " < 100\n\t" \ + ".size " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev,.-" SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev\n\t" \ + ".else\n\t" \ + ".size " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev,.-" SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev\n\t" \ + ".endif"); +#else +#define STUB_ENTRY(n) \ +asm(".text\n\t" \ + ".align 2\n\t" \ + ".globl " SYMBOL_UNDERSCORE "Stub" #n "__14nsXPTCStubBase\n\t" \ + ".type " SYMBOL_UNDERSCORE "Stub" #n "__14nsXPTCStubBase,@function\n" \ + SYMBOL_UNDERSCORE "Stub" #n "__14nsXPTCStubBase:\n\t" \ + "movl $" #n ", %eax\n\t" \ + "jmp " SYMBOL_UNDERSCORE "SharedStub\n\t" \ + ".size " SYMBOL_UNDERSCORE "Stub" #n "__14nsXPTCStubBase,.-" SYMBOL_UNDERSCORE "Stub" #n "__14nsXPTCStubBase"); +#endif + +// static nsresult SharedStub(PRUint32 methodIndex) __attribute__((regparm(1))) +asm(".text\n\t" + ".align 2\n\t" + ".type " SYMBOL_UNDERSCORE "SharedStub,@function\n\t" + SYMBOL_UNDERSCORE "SharedStub:\n\t" + "leal 0x08(%esp), %ecx\n\t" + "movl 0x04(%esp), %edx\n\t" + "jmp " SYMBOL_UNDERSCORE "PrepareAndDispatch\n\t" + ".size " SYMBOL_UNDERSCORE "SharedStub,.-" SYMBOL_UNDERSCORE "SharedStub"); + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +void +xptc_dummy() +{ +} + +#else +#error "can't find a compiler to use" +#endif /* __GNUC__ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf32.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf32.cpp new file mode 100644 index 00000000..844f55dd --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf32.cpp @@ -0,0 +1,185 @@ + +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "xptcprivate.h" + +#include <stddef.h> +#include <stdlib.h> + +// "This code is for IA64 only" + +/* Implement shared vtbl methods. */ + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, + uint64_t* intargs, uint64_t* floatargs, uint64_t* restargs) +{ + +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + nsresult result = NS_ERROR_FAILURE; + uint64_t* iargs = intargs; + uint64_t* fargs = floatargs; + PRUint8 paramCount; + PRUint8 i; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + for(i = 0; i < paramCount; ++i) + { + int isfloat = 0; + const nsXPTParamInfo& param = info->GetParam(i); + const nsXPTType& type = param.GetType(); + nsXPTCMiniVariant* dp = &dispatchParams[i]; + + if(param.IsOut() || !type.IsArithmetic()) + { +#ifdef __LP64__ + /* 64 bit pointer mode */ + dp->val.p = (void*) *iargs; +#else + /* 32 bit pointer mode */ + uint32_t* adr = (uint32_t*) iargs; + dp->val.p = (void*) (*(adr+1)); +#endif + } + else + switch(type) + { + case nsXPTType::T_I8 : dp->val.i8 = *(iargs); break; + case nsXPTType::T_I16 : dp->val.i16 = *(iargs); break; + case nsXPTType::T_I32 : dp->val.i32 = *(iargs); break; + case nsXPTType::T_I64 : dp->val.i64 = *(iargs); break; + case nsXPTType::T_U8 : dp->val.u8 = *(iargs); break; + case nsXPTType::T_U16 : dp->val.u16 = *(iargs); break; + case nsXPTType::T_U32 : dp->val.u32 = *(iargs); break; + case nsXPTType::T_U64 : dp->val.u64 = *(iargs); break; + case nsXPTType::T_FLOAT : + isfloat = 1; + if (i < 7) + dp->val.f = (float) *((double*) fargs); /* register */ + else + dp->val.u32 = *(fargs); /* memory */ + break; + case nsXPTType::T_DOUBLE : + isfloat = 1; + dp->val.u64 = *(fargs); + break; + case nsXPTType::T_BOOL : dp->val.b = *(iargs); break; + case nsXPTType::T_CHAR : dp->val.c = *(iargs); break; + case nsXPTType::T_WCHAR : dp->val.wc = *(iargs); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + if (i < 7) + { + /* we are parsing register arguments */ + if (i == 6) + { + // run out of register arguments, move on to memory arguments + iargs = restargs; + fargs = restargs; + } + else + { + ++iargs; // advance one integer register slot + if (isfloat) ++fargs; // advance float register slot if isfloat + } + } + else + { + /* we are parsing memory arguments */ + ++iargs; + ++fargs; + } + } + + result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int SharedStub(PRUint64,PRUint64,PRUint64,PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); + +/* Variable a0-a7 were put there so we can have access to the 8 input + registers on Stubxyz entry */ + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n(PRUint64 a1, \ +PRUint64 a2,PRUint64 a3,PRUint64 a4,PRUint64 a5,PRUint64 a6,PRUint64 a7) \ +{ uint64_t a0 = (uint64_t) this; \ + return SharedStub(a0,a1,a2,a3,a4,a5,a6,a7,(PRUint64) n); \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf64.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf64.cpp new file mode 100644 index 00000000..6a11f692 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf64.cpp @@ -0,0 +1,186 @@ + +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "xptcprivate.h" + +#include <stddef.h> +#include <stdlib.h> +#include <stdint.h> + +// "This code is for IA64 only" + +/* Implement shared vtbl methods. */ + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, + uint64_t* intargs, uint64_t* floatargs, uint64_t* restargs) +{ + +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + nsresult result = NS_ERROR_FAILURE; + uint64_t* iargs = intargs; + uint64_t* fargs = floatargs; + PRUint8 paramCount; + PRUint8 i; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + for(i = 0; i < paramCount; ++i) + { + int isfloat = 0; + const nsXPTParamInfo& param = info->GetParam(i); + const nsXPTType& type = param.GetType(); + nsXPTCMiniVariant* dp = &dispatchParams[i]; + + if(param.IsOut() || !type.IsArithmetic()) + { +#ifdef __LP64__ + /* 64 bit pointer mode */ + dp->val.p = (void*) *iargs; +#else + /* 32 bit pointer mode */ + uint32_t* adr = (uint32_t*) iargs; + dp->val.p = (void*) (*(adr+1)); +#endif + } + else + switch(type) + { + case nsXPTType::T_I8 : dp->val.i8 = *(iargs); break; + case nsXPTType::T_I16 : dp->val.i16 = *(iargs); break; + case nsXPTType::T_I32 : dp->val.i32 = *(iargs); break; + case nsXPTType::T_I64 : dp->val.i64 = *(iargs); break; + case nsXPTType::T_U8 : dp->val.u8 = *(iargs); break; + case nsXPTType::T_U16 : dp->val.u16 = *(iargs); break; + case nsXPTType::T_U32 : dp->val.u32 = *(iargs); break; + case nsXPTType::T_U64 : dp->val.u64 = *(iargs); break; + case nsXPTType::T_FLOAT : + isfloat = 1; + if (i < 7) + dp->val.f = (float) *((double*) fargs); /* register */ + else + dp->val.u32 = *(fargs); /* memory */ + break; + case nsXPTType::T_DOUBLE : + isfloat = 1; + dp->val.u64 = *(fargs); + break; + case nsXPTType::T_BOOL : dp->val.b = *(iargs); break; + case nsXPTType::T_CHAR : dp->val.c = *(iargs); break; + case nsXPTType::T_WCHAR : dp->val.wc = *(iargs); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + if (i < 7) + { + /* we are parsing register arguments */ + if (i == 6) + { + // run out of register arguments, move on to memory arguments + iargs = restargs; + fargs = restargs; + } + else + { + ++iargs; // advance one integer register slot + if (isfloat) ++fargs; // advance float register slot if isfloat + } + } + else + { + /* we are parsing memory arguments */ + ++iargs; + ++fargs; + } + } + + result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int SharedStub(PRUint64,PRUint64,PRUint64,PRUint64, + PRUint64,PRUint64,PRUint64,PRUint64,PRUint64); + +/* Variable a0-a7 were put there so we can have access to the 8 input + registers on Stubxyz entry */ + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n(PRUint64 a1, \ +PRUint64 a2,PRUint64 a3,PRUint64 a4,PRUint64 a5,PRUint64 a6,PRUint64 a7) \ +{ uint64_t a0 = (uint64_t) this; \ + return SharedStub(a0,a1,a2,a3,a4,a5,a6,a7,(PRUint64) n); \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_irix.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_irix.cpp new file mode 100644 index 00000000..556b5bbe --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_irix.cpp @@ -0,0 +1,226 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "xptcprivate.h" + +#if defined(IRIX) + +#if (_MIPS_SIM != _ABIN32) +#error "This code is for IRIX N32 only" +#endif + +/* + * This is for IRIX N32 ABI + * + * When we're called, the "gp" registers are stored in gprData and + * the "fp" registers are stored in fprData. There are 8 regs + * available which coorespond to the first 7 parameters of the + * function and the "this" pointer. If there are additional parms, + * they are stored on the stack at address "args". + * + */ +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint64* args, + PRUint64 *gprData, double *fprData) +{ +#define PARAM_BUFFER_COUNT 16 +#define PARAM_GPR_COUNT 7 +#define PARAM_FPR_COUNT 7 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint64* ap = args; + PRUint32 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 = (PRInt8)gprData[iCount++]; + else + dp->val.i8 = (PRInt8)*ap++; + break; + + case nsXPTType::T_I16: + if (iCount < PARAM_GPR_COUNT) + dp->val.i16 = (PRInt16)gprData[iCount++]; + else + dp->val.i16 = (PRInt16)*ap++; + break; + + case nsXPTType::T_I32: + if (iCount < PARAM_GPR_COUNT) + dp->val.i32 = (PRInt32)gprData[iCount++]; + else + dp->val.i32 = (PRInt32)*ap++; + break; + + case nsXPTType::T_I64: + if (iCount < PARAM_GPR_COUNT) + dp->val.i64 = (PRInt64)gprData[iCount++]; + else + dp->val.i64 = (PRInt64)*ap++; + break; + + case nsXPTType::T_U8: + if (iCount < PARAM_GPR_COUNT) + dp->val.u8 = (PRUint8)gprData[iCount++]; + else + dp->val.u8 = (PRUint8)*ap++; + break; + + case nsXPTType::T_U16: + if (iCount < PARAM_GPR_COUNT) + dp->val.u16 = (PRUint16)gprData[iCount++]; + else + dp->val.u16 = (PRUint16)*ap++; + break; + + case nsXPTType::T_U32: + if (iCount < PARAM_GPR_COUNT) + dp->val.u32 = (PRUint32)gprData[iCount++]; + else + dp->val.u32 = (PRUint32)*ap++; + break; + + case nsXPTType::T_U64: + if (iCount < PARAM_GPR_COUNT) + dp->val.u64 = (PRUint64)gprData[iCount++]; + else + dp->val.u64 = (PRUint64)*ap++; + break; + + case nsXPTType::T_FLOAT: + if (iCount < PARAM_FPR_COUNT) + dp->val.f = (double)fprData[iCount++]; + else + dp->val.f = *((double*)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 = (PRBool)gprData[iCount++]; + else + dp->val.b = (PRBool)*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->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + 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_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#endif diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_alpha.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_alpha.cpp new file mode 100644 index 00000000..e5b1c642 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_alpha.cpp @@ -0,0 +1,236 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Glen Nakamura <glen@imodulo.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +/* Prototype specifies unmangled function name and disables unused warning */ +static nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint64* args) +__asm__("PrepareAndDispatch") __attribute__((unused)); + +static nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint64* args) +{ + const PRUint8 PARAM_BUFFER_COUNT = 16; + const PRUint8 NUM_ARG_REGS = 6-1; // -1 for "this" pointer + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + // args[0] to args[NUM_ARG_REGS] hold floating point register values + PRUint64* ap = args + NUM_ARG_REGS; + 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 = (PRInt8) *ap; break; + case nsXPTType::T_I16 : dp->val.i16 = (PRInt16) *ap; break; + case nsXPTType::T_I32 : dp->val.i32 = (PRInt32) *ap; break; + case nsXPTType::T_I64 : dp->val.i64 = (PRInt64) *ap; break; + case nsXPTType::T_U8 : dp->val.u8 = (PRUint8) *ap; break; + case nsXPTType::T_U16 : dp->val.u16 = (PRUint16) *ap; break; + case nsXPTType::T_U32 : dp->val.u32 = (PRUint32) *ap; break; + case nsXPTType::T_U64 : dp->val.u64 = (PRUint64) *ap; break; + case nsXPTType::T_FLOAT : + if(i < NUM_ARG_REGS) + { + // floats passed via registers are stored as doubles + // in the first NUM_ARG_REGS entries in args + dp->val.u64 = (PRUint64) args[i]; + dp->val.f = (float) dp->val.d; // convert double to float + } + else + dp->val.u32 = (PRUint32) *ap; + break; + case nsXPTType::T_DOUBLE : + // doubles passed via registers are also stored + // in the first NUM_ARG_REGS entries in args + dp->val.u64 = (i < NUM_ARG_REGS) ? args[i] : *ap; + break; + case nsXPTType::T_BOOL : dp->val.b = (PRBool) *ap; break; + case nsXPTType::T_CHAR : dp->val.c = (char) *ap; break; + case nsXPTType::T_WCHAR : dp->val.wc = (PRUnichar) *ap; break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +/* + * SharedStub() + * Collects arguments and calls PrepareAndDispatch. The "methodIndex" is + * passed to this function via $1 to preserve the argument registers. + */ +__asm__( + "#### SharedStub ####\n" +".text\n\t" + ".align 5\n\t" + ".ent SharedStub\n" +"SharedStub:\n\t" + ".frame $30,96,$26,0\n\t" + ".mask 0x4000000,-96\n\t" + "ldgp $29,0($27)\n" +"$SharedStub..ng:\n\t" + "subq $30,96,$30\n\t" + "stq $26,0($30)\n\t" + ".prologue 1\n\t" + + /* + * Store arguments passed via registers to the stack. + * Floating point registers are stored as doubles and converted + * to floats in PrepareAndDispatch if necessary. + */ + "stt $f17,16($30)\n\t" /* floating point registers */ + "stt $f18,24($30)\n\t" + "stt $f19,32($30)\n\t" + "stt $f20,40($30)\n\t" + "stt $f21,48($30)\n\t" + "stq $17,56($30)\n\t" /* integer registers */ + "stq $18,64($30)\n\t" + "stq $19,72($30)\n\t" + "stq $20,80($30)\n\t" + "stq $21,88($30)\n\t" + + /* + * Call PrepareAndDispatch function. + */ + "bis $1,$1,$17\n\t" /* pass "methodIndex" */ + "addq $30,16,$18\n\t" /* pass "args" */ + "bsr $26,$PrepareAndDispatch..ng\n\t" + + "ldq $26,0($30)\n\t" + "addq $30,96,$30\n\t" + "ret $31,($26),1\n\t" + ".end SharedStub" + ); + +/* + * nsresult nsXPTCStubBase::Stub##n() + * Sets register $1 to "methodIndex" and jumps to SharedStub. + */ +#define STUB_MANGLED_ENTRY(n, symbol) \ + "#### Stub"#n" ####" "\n\t" \ + ".text" "\n\t" \ + ".align 5" "\n\t" \ + ".globl " symbol "\n\t" \ + ".ent " symbol "\n" \ +symbol ":" "\n\t" \ + ".frame $30,0,$26,0" "\n\t" \ + "ldgp $29,0($27)" "\n" \ +"$" symbol "..ng:" "\n\t" \ + ".prologue 1" "\n\t" \ + "lda $1,"#n "\n\t" \ + "br $31,$SharedStub..ng" "\n\t" \ + ".end " symbol + +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ + +#define STUB_ENTRY(n) \ +__asm__( \ + ".if "#n" < 10" "\n\t" \ + STUB_MANGLED_ENTRY(n, "_ZN14nsXPTCStubBase5Stub"#n"Ev") "\n\t" \ + ".elseif "#n" < 100" "\n\t" \ + STUB_MANGLED_ENTRY(n, "_ZN14nsXPTCStubBase6Stub"#n"Ev") "\n\t" \ + ".elseif "#n" < 1000" "\n\t" \ + STUB_MANGLED_ENTRY(n, "_ZN14nsXPTCStubBase7Stub"#n"Ev") "\n\t" \ + ".else" "\n\t" \ + ".err \"Stub"#n" >= 1000 not yet supported.\"" "\n\t" \ + ".endif" \ + ); + +#else /* not G++ V3 ABI */ + +#define STUB_ENTRY(n) \ +__asm__( \ + STUB_MANGLED_ENTRY(n, "Stub"#n"__14nsXPTCStubBase") \ + ); + +#endif /* G++ V3 ABI */ + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_m68k.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_m68k.cpp new file mode 100644 index 00000000..eb094762 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_m68k.cpp @@ -0,0 +1,146 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +extern "C" { + nsresult + PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, uint32* args) + { +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* 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; + } + + switch(type) + { + // the 8 and 16 bit types will have been promoted to 32 bits before + // being pushed onto the stack. Since the 68k is big endian, we + // need to skip over the leading high order bytes. + case nsXPTType::T_I8 : dp->val.i8 = *(((PRInt8*) ap) + 3); break; + case nsXPTType::T_I16 : dp->val.i16 = *(((PRInt16*) ap) + 1); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) ap); break; + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U8 : dp->val.u8 = *(((PRUint8*) ap) + 3); break; + case nsXPTType::T_U16 : dp->val.u16 = *(((PRUint16*)ap) + 1); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)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 = *((PRBool*) ap); break; + case nsXPTType::T_CHAR : dp->val.c = *(((char*) ap) + 3); break; + case nsXPTType::T_WCHAR : dp->val.wc = *((wchar_t*) ap); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; + } +} + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + register nsresult result; \ + __asm__ __volatile__( \ + "lea %/a6@(12), %/a0\n\t" /* args */ \ + "movl %/a0, %/sp@-\n\t" \ + "movl #"#n", %/sp@-\n\t" /* method index */ \ + "movl %/a6@(8), %/sp@-\n\t" /* this */ \ + "jbsr PrepareAndDispatch\n\t" \ + "movl %/d0, %0\n\t" \ + "addl #12, %/sp" \ + : "=d" (result) /* %0 */ \ + : \ + : "a0", "a1", "d0", "d1", "memory" ); \ + return result; \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390.cpp new file mode 100644 index 00000000..0f8502cd --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390.cpp @@ -0,0 +1,220 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +static nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, + PRUint32* a_gpr, PRUint64 *a_fpr, PRUint32 *a_ov) +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32 gpr = 1, fpr = 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 (gpr < 5) + dp->val.p = (void*) *a_gpr++, gpr++; + else + dp->val.p = (void*) *a_ov++; + continue; + } + // else + switch(type) + { + case nsXPTType::T_I8 : + if (gpr < 5) + dp->val.i8 = *((PRInt32*) a_gpr), a_gpr++, gpr++; + else + dp->val.i8 = *((PRInt32*) a_ov ), a_ov++; + break; + case nsXPTType::T_I16 : + if (gpr < 5) + dp->val.i16 = *((PRInt32*) a_gpr), a_gpr++, gpr++; + else + dp->val.i16 = *((PRInt32*) a_ov ), a_ov++; + break; + case nsXPTType::T_I32 : + if (gpr < 5) + dp->val.i32 = *((PRInt32*) a_gpr), a_gpr++, gpr++; + else + dp->val.i32 = *((PRInt32*) a_ov ), a_ov++; + break; + case nsXPTType::T_I64 : + if (gpr < 4) + dp->val.i64 = *((PRInt64*) a_gpr), a_gpr+=2, gpr+=2; + else + dp->val.i64 = *((PRInt64*) a_ov ), a_ov+=2, gpr=5; + break; + case nsXPTType::T_U8 : + if (gpr < 5) + dp->val.u8 = *((PRUint32*)a_gpr), a_gpr++, gpr++; + else + dp->val.u8 = *((PRUint32*)a_ov ), a_ov++; + break; + case nsXPTType::T_U16 : + if (gpr < 5) + dp->val.u16 = *((PRUint32*)a_gpr), a_gpr++, gpr++; + else + dp->val.u16 = *((PRUint32*)a_ov ), a_ov++; + break; + case nsXPTType::T_U32 : + if (gpr < 5) + dp->val.u32 = *((PRUint32*)a_gpr), a_gpr++, gpr++; + else + dp->val.u32 = *((PRUint32*)a_ov ), a_ov++; + break; + case nsXPTType::T_U64 : + if (gpr < 4) + dp->val.u64 = *((PRUint64*)a_gpr), a_gpr+=2, gpr+=2; + else + dp->val.u64 = *((PRUint64*)a_ov ), a_ov+=2, gpr=5; + break; + case nsXPTType::T_FLOAT : + if (fpr < 2) + dp->val.f = *((float*) a_fpr), a_fpr++, fpr++; + else + dp->val.f = *((float*) a_ov ), a_ov++; + break; + case nsXPTType::T_DOUBLE : + if (fpr < 2) + dp->val.d = *((double*) a_fpr), a_fpr++, fpr++; + else + dp->val.d = *((double*) a_ov ), a_ov+=2; + break; + case nsXPTType::T_BOOL : + if (gpr < 5) + dp->val.b = *((PRUint32*)a_gpr), a_gpr++, gpr++; + else + dp->val.b = *((PRUint32*)a_ov ), a_ov++; + break; + case nsXPTType::T_CHAR : + if (gpr < 5) + dp->val.c = *((PRUint32*)a_gpr), a_gpr++, gpr++; + else + dp->val.c = *((PRUint32*)a_ov ), a_ov++; + break; + case nsXPTType::T_WCHAR : + if (gpr < 5) + dp->val.wc = *((PRUint32*)a_gpr), a_gpr++, gpr++; + else + dp->val.wc = *((PRUint32*)a_ov ), a_ov++; + break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + PRUint32 a_gpr[4]; \ + PRUint64 a_fpr[2]; \ + PRUint32 *a_ov; \ + \ + __asm__ __volatile__ \ + ( \ + "l %0,0(15)\n\t" \ + "ahi %0,96\n\t" \ + "stm 3,6,0(%3)\n\t" \ + "std 0,%1\n\t" \ + "std 2,%2\n\t" \ + : "=&a" (a_ov), \ + "=m" (a_fpr[0]), \ + "=m" (a_fpr[1]) \ + : "a" (a_gpr) \ + : "memory", "cc", \ + "3", "4", "5", "6" \ + ); \ + \ + return PrepareAndDispatch(this, n, a_gpr, a_fpr, a_ov); \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390x.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390x.cpp new file mode 100644 index 00000000..9a645dd1 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390x.cpp @@ -0,0 +1,224 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +static nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, + PRUint64* a_gpr, PRUint64 *a_fpr, PRUint64 *a_ov) +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32 gpr = 1, fpr = 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 (gpr < 5) + dp->val.p = (void*) *a_gpr++, gpr++; + else + dp->val.p = (void*) *a_ov++; + continue; + } + // else + switch(type) + { + case nsXPTType::T_I8 : + if (gpr < 5) + dp->val.i8 = *((PRInt64*) a_gpr), a_gpr++, gpr++; + else + dp->val.i8 = *((PRInt64*) a_ov ), a_ov++; + break; + case nsXPTType::T_I16 : + if (gpr < 5) + dp->val.i16 = *((PRInt64*) a_gpr), a_gpr++, gpr++; + else + dp->val.i16 = *((PRInt64*) a_ov ), a_ov++; + break; + case nsXPTType::T_I32 : + if (gpr < 5) + dp->val.i32 = *((PRInt64*) a_gpr), a_gpr++, gpr++; + else + dp->val.i32 = *((PRInt64*) a_ov ), a_ov++; + break; + case nsXPTType::T_I64 : + if (gpr < 5) + dp->val.i64 = *((PRInt64*) a_gpr), a_gpr++, gpr++; + else + dp->val.i64 = *((PRInt64*) a_ov ), a_ov++; + break; + case nsXPTType::T_U8 : + if (gpr < 5) + dp->val.u8 = *((PRUint64*)a_gpr), a_gpr++, gpr++; + else + dp->val.u8 = *((PRUint64*)a_ov ), a_ov++; + break; + case nsXPTType::T_U16 : + if (gpr < 5) + dp->val.u16 = *((PRUint64*)a_gpr), a_gpr++, gpr++; + else + dp->val.u16 = *((PRUint64*)a_ov ), a_ov++; + break; + case nsXPTType::T_U32 : + if (gpr < 5) + dp->val.u32 = *((PRUint64*)a_gpr), a_gpr++, gpr++; + else + dp->val.u32 = *((PRUint64*)a_ov ), a_ov++; + break; + case nsXPTType::T_U64 : + if (gpr < 5) + dp->val.u64 = *((PRUint64*)a_gpr), a_gpr++, gpr++; + else + dp->val.u64 = *((PRUint64*)a_ov ), a_ov++; + break; + case nsXPTType::T_FLOAT : + if (fpr < 4) + dp->val.f = *((float*) a_fpr), a_fpr++, fpr++; + else + dp->val.f = *(((float*) a_ov )+1), a_ov++; + break; + case nsXPTType::T_DOUBLE : + if (fpr < 4) + dp->val.d = *((double*) a_fpr), a_fpr++, fpr++; + else + dp->val.d = *((double*) a_ov ), a_ov++; + break; + case nsXPTType::T_BOOL : + if (gpr < 5) + dp->val.b = *((PRUint64*)a_gpr), a_gpr++, gpr++; + else + dp->val.b = *((PRUint64*)a_ov ), a_ov++; + break; + case nsXPTType::T_CHAR : + if (gpr < 5) + dp->val.c = *((PRUint64*)a_gpr), a_gpr++, gpr++; + else + dp->val.c = *((PRUint64*)a_ov ), a_ov++; + break; + case nsXPTType::T_WCHAR : + if (gpr < 5) + dp->val.wc = *((PRUint64*)a_gpr), a_gpr++, gpr++; + else + dp->val.wc = *((PRUint64*)a_ov ), a_ov++; + break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + PRUint64 a_gpr[4]; \ + PRUint64 a_fpr[4]; \ + PRUint64 *a_ov; \ + \ + __asm__ __volatile__ \ + ( \ + "lg %0,0(15)\n\t" \ + "aghi %0,160\n\t" \ + "stmg 3,6,0(%5)\n\t"\ + "std 0,%1\n\t" \ + "std 2,%2\n\t" \ + "std 4,%3\n\t" \ + "std 6,%4\n\t" \ + : "=&a" (a_ov), \ + "=m" (a_fpr[0]), \ + "=m" (a_fpr[1]), \ + "=m" (a_fpr[2]), \ + "=m" (a_fpr[3]) \ + : "a" (a_gpr) \ + : "memory", "cc", \ + "3", "4", "5", "6" \ + ); \ + \ + return PrepareAndDispatch(this, n, a_gpr, a_fpr, a_ov); \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_mips.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_mips.cpp new file mode 100644 index 00000000..4d60f7be --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_mips.cpp @@ -0,0 +1,131 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * Version: MPL 1.1 + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp, Inc. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "xptcprivate.h" + +/* + * This is for MIPS O32 ABI + * Args contains a0-3 and then the stack. + * Because a0 is 'this', we want to skip it + */ +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args) +{ + args++; // always skip over a0 + +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* 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; + } + + dp->val.p = (void*) *ap; + + switch(type) + { + case nsXPTType::T_I64 : + if ((PRWord)ap & 4) ap++; + dp->val.i64 = *((PRInt64*) ap); ap++; + break; + case nsXPTType::T_U64 : + if ((PRWord)ap & 4) ap++; + dp->val.u64 = *((PRInt64*) ap); ap++; + break; + case nsXPTType::T_DOUBLE: + if ((PRWord)ap & 4) ap++; + dp->val.d = *((double*) ap); ap++; + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#define STUB_ENTRY(n) // done in the .s file + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_netbsd_m68k.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_netbsd_m68k.cpp new file mode 100644 index 00000000..4069a6bc --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_netbsd_m68k.cpp @@ -0,0 +1,147 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if !defined(__NetBSD__) || !defined(__m68k__) +#error This code is for NetBSD/m68k only +#endif + +extern "C" { + static nsresult + PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, uint32* args) + { +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* 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; + } + + switch(type) + { + // the 8 and 16 bit types will have been promoted to 32 bits before + // being pushed onto the stack. Since the 68k is big endian, we + // need to skip over the leading high order bytes. + case nsXPTType::T_I8 : dp->val.i8 = *(((PRInt8*) ap) + 3); break; + case nsXPTType::T_I16 : dp->val.i16 = *(((PRInt16*) ap) + 1); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) ap); break; + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U8 : dp->val.u8 = *(((PRUint8*) ap) + 3); break; + case nsXPTType::T_U16 : dp->val.u16 = *(((PRUint16*)ap) + 1); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)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 = *((PRBool*) ap); break; + case nsXPTType::T_CHAR : dp->val.c = *(((char*) ap) + 3); break; + // wchar_t is an int (32 bits) on NetBSD + case nsXPTType::T_WCHAR : dp->val.wc = *((wchar_t*) ap); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; + } +} + +#define STUB_ENTRY(n) \ +__asm__( \ + ".global _Stub"#n"__14nsXPTCStubBase\n\t" \ +"_Stub"#n"__14nsXPTCStubBase:\n\t" \ + "link a6,#0 \n\t" \ + "lea a6@(12), a0 \n\t" /* pointer to args */ \ + "movl a0, sp@- \n\t" \ + "movl #"#n", sp@- \n\t" /* method index */ \ + "movl a6@(8), sp@- \n\t" /* this */ \ + "jbsr _PrepareAndDispatch \n\t" \ + "unlk a6 \n\t" \ + "rts \n\t" \ +); + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_openvms_alpha.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_openvms_alpha.cpp new file mode 100644 index 00000000..c4d1b364 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_openvms_alpha.cpp @@ -0,0 +1,147 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +extern "C" { + +nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint64* args) +{ + const PRUint8 PARAM_BUFFER_COUNT = 16; + const PRUint8 NUM_ARG_REGS = 6-1; // -1 for "this" pointer + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + // args[0] to args[NUM_ARG_REGS] hold floating point register values + PRUint64* ap = args + NUM_ARG_REGS; + 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 = (PRInt8) *ap; break; + case nsXPTType::T_I16 : dp->val.i16 = (PRInt16) *ap; break; + case nsXPTType::T_I32 : dp->val.i32 = (PRInt32) *ap; break; + case nsXPTType::T_I64 : dp->val.i64 = (PRInt64) *ap; break; + case nsXPTType::T_U8 : dp->val.u8 = (PRUint8) *ap; break; + case nsXPTType::T_U16 : dp->val.u16 = (PRUint16) *ap; break; + case nsXPTType::T_U32 : dp->val.u32 = (PRUint32) *ap; break; + case nsXPTType::T_U64 : dp->val.u64 = (PRUint64) *ap; break; + case nsXPTType::T_FLOAT : + if(i < NUM_ARG_REGS) + { + // floats passed via registers are stored as doubles + // in the first NUM_ARG_REGS entries in args + dp->val.u64 = (PRUint64) args[i]; + dp->val.f = (float) dp->val.d; // convert double to float + } + else + dp->val.u32 = (PRUint32) *ap; + break; + case nsXPTType::T_DOUBLE : + // doubles passed via registers are also stored + // in the first NUM_ARG_REGS entries in args + dp->val.u64 = (i < NUM_ARG_REGS) ? args[i] : *ap; + break; + case nsXPTType::T_BOOL : dp->val.b = (PRBool) *ap; break; + case nsXPTType::T_CHAR : dp->val.c = (char) *ap; break; + case nsXPTType::T_WCHAR : dp->val.wc = (PRUnichar) *ap; break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +} + +#define STUB_ENTRY(n) /* This is in the ASM file */ + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_osf1_alpha.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_osf1_alpha.cpp new file mode 100644 index 00000000..cd8fe40b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_osf1_alpha.cpp @@ -0,0 +1,149 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +/* contributed by Glen Nakamura <glen.nakamura@usa.net> */ + +#include "xptcprivate.h" + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint64* args) +{ + const PRUint8 PARAM_BUFFER_COUNT = 16; + const PRUint8 NUM_ARG_REGS = 6-1; // -1 for "this" pointer + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + // args[0] to args[NUM_ARG_REGS] hold floating point register values + PRUint64* ap = args + NUM_ARG_REGS; + 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 = (PRInt8) *ap; break; + case nsXPTType::T_I16 : dp->val.i16 = (PRInt16) *ap; break; + case nsXPTType::T_I32 : dp->val.i32 = (PRInt32) *ap; break; + case nsXPTType::T_I64 : dp->val.i64 = (PRInt64) *ap; break; + case nsXPTType::T_U8 : dp->val.u8 = (PRUint8) *ap; break; + case nsXPTType::T_U16 : dp->val.u16 = (PRUint16) *ap; break; + case nsXPTType::T_U32 : dp->val.u32 = (PRUint32) *ap; break; + case nsXPTType::T_U64 : dp->val.u64 = (PRUint64) *ap; break; + case nsXPTType::T_FLOAT : + if(i < NUM_ARG_REGS) + { + // floats passed via registers are stored as doubles + // in the first NUM_ARG_REGS entries in args + dp->val.u64 = (PRUint64) args[i]; + dp->val.f = (float) dp->val.d; // convert double to float + } + else + dp->val.u32 = (PRUint32) *ap; + break; + case nsXPTType::T_DOUBLE : + // doubles passed via registers are also stored + // in the first NUM_ARG_REGS entries in args + dp->val.u64 = (i < NUM_ARG_REGS) ? args[i] : *ap; + break; + case nsXPTType::T_BOOL : dp->val.b = (PRBool) *ap; break; + case nsXPTType::T_CHAR : dp->val.c = (char) *ap; break; + case nsXPTType::T_WCHAR : dp->val.wc = (PRUnichar) *ap; break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +/* + * nsresult nsXPTCStubBase::Stub##n() ;\ + * Sets arguments to registers and calls PrepareAndDispatch. + * This is defined in the ASM file. + */ +#define STUB_ENTRY(n) \ + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_pa32.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_pa32.cpp new file mode 100644 index 00000000..b3a42442 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_pa32.cpp @@ -0,0 +1,176 @@ + +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if _HPUX +#error "This code is for HP-PA RISC 32 bit mode only" +#endif + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, + PRUint32* args, PRUint32* floatargs) +{ + + typedef struct { + uint32 hi; + uint32 lo; + } DU; + +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRInt32 regwords = 1; /* self pointer is not in the variant records */ + nsresult result = NS_ERROR_FAILURE; + PRUint8 paramCount; + PRUint8 i; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + for(i = 0; i < paramCount; ++i, --args) + { + const nsXPTParamInfo& param = info->GetParam(i); + const nsXPTType& type = param.GetType(); + nsXPTCMiniVariant* dp = &dispatchParams[i]; + + if(param.IsOut() || !type.IsArithmetic()) + { + dp->val.p = (void*) *args; + ++regwords; + continue; + } + switch(type) + { + case nsXPTType::T_I8 : dp->val.i8 = *((PRInt32*) args); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt32*) args); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) args); break; + case nsXPTType::T_DOUBLE : + if (regwords & 1) + { + ++regwords; /* align on double word */ + --args; + } + if (regwords == 0 || regwords == 2) + { + dp->val.d=*((double*) (floatargs + regwords)); + --args; + } + else + { + dp->val.d = *((double*) --args); + } + regwords += 2; + continue; + case nsXPTType::T_U64 : + case nsXPTType::T_I64 : + if (regwords & 1) + { + ++regwords; /* align on double word */ + --args; + } + ((DU *)dp)->lo = *((PRUint32*) args); + ((DU *)dp)->hi = *((PRUint32*) --args); + regwords += 2; + continue; + case nsXPTType::T_FLOAT : + if (regwords >= 4) + dp->val.f = *((float*) args); + else + dp->val.f = *((float*) floatargs+4+regwords); + break; + case nsXPTType::T_U8 : dp->val.u8 = *((PRUint32*) args); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint32*) args); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*) args); break; + case nsXPTType::T_BOOL : dp->val.b = *((PRBool*) args); break; + case nsXPTType::T_CHAR : dp->val.c = *((PRUint32*) args); break; + case nsXPTType::T_WCHAR : dp->val.wc = *((PRInt32*) args); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + ++regwords; + } + + result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int SharedStub(int); + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + return SharedStub(n); \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix.cpp new file mode 100644 index 00000000..870669d7 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix.cpp @@ -0,0 +1,228 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if defined(AIX) + +/* + For PPC (AIX & MAC), the first 8 integral and the first 13 f.p. parameters + arrive in a separate chunk of data that has been loaded from the registers. + The args pointer has been set to the start of the parameters BEYOND the ones + arriving in registers +*/ +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, PRUint32 *gprData, double *fprData) +{ + typedef struct { + uint32 hi; + uint32 lo; // have to move 64 bit entities as 32 bit halves since + } DU; // stack slots are not guaranteed 16 byte aligned + +#define PARAM_BUFFER_COUNT 16 +#define PARAM_GPR_COUNT 7 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* ap = args; + PRUint32 iCount = 0; + PRUint32 fpCount = 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 = (PRInt8) gprData[iCount++]; + else + dp->val.i8 = (PRInt8) *ap++; + break; + case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT) + dp->val.i16 = (PRInt16) gprData[iCount++]; + else + dp->val.i16 = (PRInt16) *ap++; + break; + case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT) + dp->val.i32 = (PRInt32) gprData[iCount++]; + else + dp->val.i32 = (PRInt32) *ap++; + break; + case nsXPTType::T_I64 : if (iCount < PARAM_GPR_COUNT) + ((DU *)dp)->hi = (PRInt32) gprData[iCount++]; + else + ((DU *)dp)->hi = (PRInt32) *ap++; + if (iCount < PARAM_GPR_COUNT) + ((DU *)dp)->lo = (PRUint32) gprData[iCount++]; + else + ((DU *)dp)->lo = (PRUint32) *ap++; + break; + case nsXPTType::T_U8 : if (iCount < PARAM_GPR_COUNT) + dp->val.u8 = (PRUint8) gprData[iCount++]; + else + dp->val.u8 = (PRUint8) *ap++; + break; + case nsXPTType::T_U16 : if (iCount < PARAM_GPR_COUNT) + dp->val.u16 = (PRUint16) gprData[iCount++]; + else + dp->val.u16 = (PRUint16) *ap++; + break; + case nsXPTType::T_U32 : if (iCount < PARAM_GPR_COUNT) + dp->val.u32 = (PRUint32) gprData[iCount++]; + else + dp->val.u32 = (PRUint32) *ap++; + break; + case nsXPTType::T_U64 : if (iCount < PARAM_GPR_COUNT) + ((DU *)dp)->hi = (PRUint32) gprData[iCount++]; + else + ((DU *)dp)->hi = (PRUint32) *ap++; + if (iCount < PARAM_GPR_COUNT) + ((DU *)dp)->lo = (PRUint32) gprData[iCount++]; + else + ((DU *)dp)->lo = (PRUint32) *ap++; + break; + case nsXPTType::T_FLOAT : if (fpCount < 13) { + dp->val.f = (float) fprData[fpCount++]; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + } + else + dp->val.f = *((float*) ap++); + break; + case nsXPTType::T_DOUBLE : if (fpCount < 13) { + dp->val.d = (double) fprData[fpCount++]; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + } + else { + dp->val.f = *((double*) ap); + ap += 2; + } + break; + case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT) + dp->val.b = (PRBool) gprData[iCount++]; + else + dp->val.b = (PRBool) *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->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int SharedStub(int); + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + return SharedStub(n); \ +} \ + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#endif /* AIX */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix64.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix64.cpp new file mode 100644 index 00000000..cf2ddba9 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix64.cpp @@ -0,0 +1,215 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/LGPL 2.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by IBM are + * Copyright (C) 2002, International Business Machines Corporation. + * All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the LGPL or the GPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if defined(AIX) + +/* + For PPC (AIX & MAC), the first 8 integral and the first 13 f.p. parameters + arrive in a separate chunk of data that has been loaded from the registers. + The args pointer has been set to the start of the parameters BEYOND the ones + arriving in registers +*/ +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint64 methodIndex, PRUint64* args, PRUint64 *gprData, double *fprData) +{ + +#define PARAM_BUFFER_COUNT 16 +#define PARAM_GPR_COUNT 7 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint64* ap = args; + PRUint32 iCount = 0; + PRUint32 fpCount = 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 = (PRInt8) gprData[iCount++]; + else + dp->val.i8 = (PRInt8) *ap++; + break; + case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT) + dp->val.i16 = (PRInt16) gprData[iCount++]; + else + dp->val.i16 = (PRInt16) *ap++; + break; + case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT) + dp->val.i32 = (PRInt32) gprData[iCount++]; + else + dp->val.i32 = (PRInt32) *ap++; + break; + case nsXPTType::T_I64 : if (iCount < PARAM_GPR_COUNT) + dp->val.i64 = (PRInt64) gprData[iCount++]; + else + dp->val.i64 = (PRInt64) *ap++; + break; + case nsXPTType::T_U8 : if (iCount < PARAM_GPR_COUNT) + dp->val.u8 = (PRUint8) gprData[iCount++]; + else + dp->val.u8 = (PRUint8) *ap++; + break; + case nsXPTType::T_U16 : if (iCount < PARAM_GPR_COUNT) + dp->val.u16 = (PRUint16) gprData[iCount++]; + else + dp->val.u16 = (PRUint16) *ap++; + break; + case nsXPTType::T_U32 : if (iCount < PARAM_GPR_COUNT) + dp->val.u32 = (PRUint32) gprData[iCount++]; + else + dp->val.u32 = (PRUint32) *ap++; + break; + case nsXPTType::T_U64 : if (iCount < PARAM_GPR_COUNT) + dp->val.u64 = (PRUint64) gprData[iCount++]; + else + dp->val.u64 = (PRUint64) *ap++; + break; + case nsXPTType::T_FLOAT : if (fpCount < 13) { + dp->val.f = (float) fprData[fpCount++]; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + } + else + dp->val.f = *((float*) ap++); + break; + case nsXPTType::T_DOUBLE : if (fpCount < 13) { + dp->val.d = (double) fprData[fpCount++]; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + } + else { + dp->val.f = *((double*) ap); + ap += 2; + } + break; + case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT) + dp->val.b = (PRBool) gprData[iCount++]; + else + dp->val.b = (PRBool) *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->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int SharedStub(int); + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + return SharedStub(n); \ +} \ + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#endif /* AIX */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_linux.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_linux.cpp new file mode 100644 index 00000000..b1c98571 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_linux.cpp @@ -0,0 +1,253 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Franz.Sirl-kernel@lauterbach.com (Franz Sirl) + * beard@netscape.com (Patrick Beard) + * waterson@netscape.com (Chris Waterson) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Implement shared vtbl methods. + +#include "xptcprivate.h" + +// The Linux/PPC ABI (aka PPC/SYSV ABI) passes the first 8 integral +// parameters and the first 8 floating point parameters in registers +// (r3-r10 and f1-f8), no stack space is allocated for these by the +// caller. The rest of the parameters are passed in the callers stack +// area. The stack pointer has to retain 16-byte alignment, longlongs +// and doubles are aligned on 8-byte boundaries. + +#define PARAM_BUFFER_COUNT 16 +#define GPR_COUNT 8 +#define FPR_COUNT 8 + +// PrepareAndDispatch() is called by SharedStub() and calls the actual method. +// +// - 'args[]' contains the arguments passed on stack +// - 'gprData[]' contains the arguments passed in integer registers +// - 'fprData[]' contains the arguments passed in floating point registers +// +// The parameters are mapped into an array of type 'nsXPTCMiniVariant' +// and then the method gets called. + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, + PRUint32 methodIndex, + PRUint32* args, + PRUint32 *gprData, + double *fprData) +{ + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint32 paramCount; + PRUint32 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + if (! iface_info) + return NS_ERROR_UNEXPECTED; + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no method info"); + if (! info) + return NS_ERROR_UNEXPECTED; + + 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"); + if (! dispatchParams) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32* ap = args; + PRUint32 gpr = 1; // skip one GPR register + PRUint32 fpr = 0; + PRUint32 tempu32; + PRUint64 tempu64; + + 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 == nsXPTType::T_DOUBLE) { + if (fpr < FPR_COUNT) + dp->val.d = fprData[fpr++]; + else { + if ((PRUint32) ap & 4) ap++; // doubles are 8-byte aligned on stack + dp->val.d = *(double*) ap; + ap += 2; + } + continue; + } + else if (!param.IsOut() && type == nsXPTType::T_FLOAT) { + if (fpr < FPR_COUNT) + dp->val.f = (float) fprData[fpr++]; // in registers floats are passed as doubles + else + dp->val.f = *(float*) ap++; + continue; + } + else if (!param.IsOut() && (type == nsXPTType::T_I64 + || type == nsXPTType::T_U64)) { + if (gpr & 1) gpr++; // longlongs are aligned in odd/even register pairs, eg. r5/r6 + if ((gpr + 1) < GPR_COUNT) { + tempu64 = *(PRUint64*) &gprData[gpr]; + gpr += 2; + } + else { + if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack + tempu64 = *(PRUint64*) ap; + ap += 2; + } + } + else { + if (gpr < GPR_COUNT) + tempu32 = gprData[gpr++]; + else + tempu32 = *ap++; + } + + if(param.IsOut() || !type.IsArithmetic()) { + dp->val.p = (void*) tempu32; + continue; + } + + switch(type) { + case nsXPTType::T_I8: dp->val.i8 = (PRInt8) tempu32; break; + case nsXPTType::T_I16: dp->val.i16 = (PRInt16) tempu32; break; + case nsXPTType::T_I32: dp->val.i32 = (PRInt32) tempu32; break; + case nsXPTType::T_I64: dp->val.i64 = (PRInt64) tempu64; break; + case nsXPTType::T_U8: dp->val.u8 = (PRUint8) tempu32; break; + case nsXPTType::T_U16: dp->val.u16 = (PRUint16) tempu32; break; + case nsXPTType::T_U32: dp->val.u32 = (PRUint32) tempu32; break; + case nsXPTType::T_U64: dp->val.u64 = (PRUint64) tempu64; break; + case nsXPTType::T_BOOL: dp->val.b = (PRBool) tempu32; break; + case nsXPTType::T_CHAR: dp->val.c = (char) tempu32; break; + case nsXPTType::T_WCHAR: dp->val.wc = (wchar_t) tempu32; break; + + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if (dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +// Load r11 with the constant 'n' and branch to SharedStub(). +// +// XXX Yes, it's ugly that we're relying on gcc's name-mangling here; +// however, it's quick, dirty, and'll break when the ABI changes on +// us, which is what we want ;-). + +#if __GXX_ABI_VERSION < 100 +// gcc-2 version +# define STUB_ENTRY(n) \ +__asm__ ( \ + ".section \".text\" \n\t" \ + ".align 2 \n\t" \ + ".globl Stub"#n"__14nsXPTCStubBase \n\t" \ + ".type Stub"#n"__14nsXPTCStubBase,@function \n\n" \ + \ +"Stub"#n"__14nsXPTCStubBase: \n\t" \ + "li 11,"#n" \n\t" \ + "b SharedStub@local \n" \ +); +#else +// gcc-3 version +// +// As G++3 ABI contains the length of the functionname in the mangled +// name, it is difficult to get a generic assembler mechanism like +// in the G++ 2.95 case. +// Create names would be like: +// _ZN14nsXPTCStubBase5Stub1Ev +// _ZN14nsXPTCStubBase6Stub12Ev +// _ZN14nsXPTCStubBase7Stub123Ev +// _ZN14nsXPTCStubBase8Stub1234Ev +// etc. +// Use assembler directives to get the names right... + +# define STUB_ENTRY(n) \ +__asm__ ( \ + ".align 2 \n\t" \ + ".if "#n" < 10 \n\t" \ + ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \ + ".type _ZN14nsXPTCStubBase5Stub"#n"Ev,@function \n\n" \ +"_ZN14nsXPTCStubBase5Stub"#n"Ev: \n\t" \ + \ + ".elseif "#n" < 100 \n\t" \ + ".globl _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \ + ".type _ZN14nsXPTCStubBase6Stub"#n"Ev,@function \n\n" \ +"_ZN14nsXPTCStubBase6Stub"#n"Ev: \n\t" \ + \ + ".elseif "#n" < 1000 \n\t" \ + ".globl _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \ + ".type _ZN14nsXPTCStubBase7Stub"#n"Ev,@function \n\n" \ +"_ZN14nsXPTCStubBase7Stub"#n"Ev: \n\t" \ + \ + ".else \n\t" \ + ".err \"stub number "#n" >= 1000 not yet supported\"\n" \ + ".endif \n\t" \ + \ + "li 11,"#n" \n\t" \ + "b SharedStub@local \n" \ +); +#endif + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp new file mode 100644 index 00000000..68d572ca --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp @@ -0,0 +1,217 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Franz.Sirl-kernel@lauterbach.com (Franz Sirl) + * beard@netscape.com (Patrick Beard) + * waterson@netscape.com (Chris Waterson) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Implement shared vtbl methods. + +#include "xptcprivate.h" + +// The Linux/PPC ABI (aka PPC/SYSV ABI) passes the first 8 integral +// parameters and the first 8 floating point parameters in registers +// (r3-r10 and f1-f8), no stack space is allocated for these by the +// caller. The rest of the parameters are passed in the callers stack +// area. The stack pointer has to retain 16-byte alignment, longlongs +// and doubles are aligned on 8-byte boundaries. + +#define PARAM_BUFFER_COUNT 16 +#define GPR_COUNT 8 +#define FPR_COUNT 8 + +// PrepareAndDispatch() is called by SharedStub() and calls the actual method. +// +// - 'args[]' contains the arguments passed on stack +// - 'gprData[]' contains the arguments passed in integer registers +// - 'fprData[]' contains the arguments passed in floating point registers +// +// The parameters are mapped into an array of type 'nsXPTCMiniVariant' +// and then the method gets called. + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, + PRUint32 methodIndex, + PRUint32* args, + PRUint32 *gprData, + double *fprData) +{ + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint32 paramCount; + PRUint32 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + if (! iface_info) + return NS_ERROR_UNEXPECTED; + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no method info"); + if (! info) + return NS_ERROR_UNEXPECTED; + + 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"); + if (! dispatchParams) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32* ap = args; + PRUint32 gpr = 1; // skip one GPR register + PRUint32 fpr = 0; + PRUint32 tempu32; + PRUint64 tempu64; + + 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 == nsXPTType::T_DOUBLE) { + if (fpr < FPR_COUNT) + dp->val.d = fprData[fpr++]; + else { + if ((PRUint32) ap & 4) ap++; // doubles are 8-byte aligned on stack + dp->val.d = *(double*) ap; + ap += 2; + if (gpr < GPR_COUNT) + gpr += 2; + } + continue; + } + else if (!param.IsOut() && type == nsXPTType::T_FLOAT) { + if (fpr < FPR_COUNT) + dp->val.f = (float) fprData[fpr++]; // in registers floats are passed as doubles + else { + dp->val.f = *(float*) ap; + ap += 1; + if (gpr < GPR_COUNT) + gpr += 1; + } + continue; + } + else if (!param.IsOut() && (type == nsXPTType::T_I64 + || type == nsXPTType::T_U64)) { + if (gpr & 1) gpr++; // longlongs are aligned in odd/even register pairs, eg. r5/r6 + if ((gpr + 1) < GPR_COUNT) { + tempu64 = *(PRUint64*) &gprData[gpr]; + gpr += 2; + } + else { + if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack + tempu64 = *(PRUint64*) ap; + ap += 2; + } + } + else { + if (gpr < GPR_COUNT) + tempu32 = gprData[gpr++]; + else + tempu32 = *ap++; + } + + if(param.IsOut() || !type.IsArithmetic()) { + dp->val.p = (void*) tempu32; + continue; + } + + switch(type) { + case nsXPTType::T_I8: dp->val.i8 = (PRInt8) tempu32; break; + case nsXPTType::T_I16: dp->val.i16 = (PRInt16) tempu32; break; + case nsXPTType::T_I32: dp->val.i32 = (PRInt32) tempu32; break; + case nsXPTType::T_I64: dp->val.i64 = (PRInt64) tempu64; break; + case nsXPTType::T_U8: dp->val.u8 = (PRUint8) tempu32; break; + case nsXPTType::T_U16: dp->val.u16 = (PRUint16) tempu32; break; + case nsXPTType::T_U32: dp->val.u32 = (PRUint32) tempu32; break; + case nsXPTType::T_U64: dp->val.u64 = (PRUint64) tempu64; break; + case nsXPTType::T_BOOL: dp->val.b = (PRBool) tempu32; break; + case nsXPTType::T_CHAR: dp->val.c = (char) tempu32; break; + case nsXPTType::T_WCHAR: dp->val.wc = (wchar_t) tempu32; break; + + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if (dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +// Load r11 with the constant 'n' and branch to SharedStub(). +// +// XXX Yes, it's ugly that we're relying on gcc's name-mangling here; +// however, it's quick, dirty, and'll break when the ABI changes on +// us, which is what we want ;-). + +#define STUB_ENTRY(n) \ +__asm__ ( \ + ".section \".text\" \n\t" \ + ".align 2 \n\t" \ + ".globl Stub"#n"__14nsXPTCStubBase \n\t" \ + ".type Stub"#n"__14nsXPTCStubBase,@function \n\n" \ + \ +"Stub"#n"__14nsXPTCStubBase: \n\t" \ + "li 11,"#n" \n\t" \ + "b SharedStub@local \n" \ +); + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_rhapsody.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_rhapsody.cpp new file mode 100644 index 00000000..fcf96d4f --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_rhapsody.cpp @@ -0,0 +1,254 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +/* + For mac, the first 8 integral and the first 13 f.p. parameters arrive + in a separate chunk of data that has been loaded from the registers. The + args pointer has been set to the start of the parameters BEYOND the ones + arriving in registers +*/ +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, PRUint32 *gprData, double *fprData) +{ +#define PARAM_BUFFER_COUNT 16 +#define PARAM_GPR_COUNT 7 + + // fprintf(stderr, "PrepareAndDispatch %p, %d, %p, %p, %p\n", self, methodIndex, args, gprData, fprData); + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* ap = args; + PRUint32 iCount = 0; + PRUint32 fpCount = 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 = (PRInt8) gprData[iCount++]; + else + dp->val.i8 = (PRInt8) *ap++; + break; + case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT) + dp->val.i16 = (PRInt16) gprData[iCount++]; + else + dp->val.i16 = (PRInt16) *ap++; + break; + case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT) + dp->val.i32 = (PRInt32) gprData[iCount++]; + else + dp->val.i32 = (PRInt32) *ap++; + break; + + case nsXPTType::T_I64 : + { + PRUint64 tempu64; + if (iCount & 1) iCount++; // longlongs are aligned in odd/even register pairs, eg. r5/r6 + if ((iCount + 1) < PARAM_GPR_COUNT) { + tempu64 = *(PRUint64*) &gprData[iCount]; + iCount += 2; + } + else { + if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack + tempu64 = *(PRUint64*) ap; + ap += 2; + } + dp->val.i64 = (PRUint64)tempu64; + } + break; + +#if 0 + case nsXPTType::T_I64 : if (iCount < PARAM_GPR_COUNT) + dp->val.i64.hi = (PRInt32) gprData[iCount++]; + else + dp->val.i64.hi = (PRInt32) *ap++; + if (iCount < PARAM_GPR_COUNT) + dp->val.i64.lo = (PRUint32) gprData[iCount++]; + else + dp->val.i64.lo = (PRUint32) *ap++; + break; +#endif + case nsXPTType::T_U8 : if (iCount < PARAM_GPR_COUNT) + dp->val.i8 = (PRUint8) gprData[iCount++]; + else + dp->val.i8 = (PRUint8) *ap++; + break; + case nsXPTType::T_U16 : if (iCount < PARAM_GPR_COUNT) + dp->val.i16 = (PRUint16) gprData[iCount++]; + else + dp->val.i16 = (PRUint16) *ap++; + break; + case nsXPTType::T_U32 : if (iCount < PARAM_GPR_COUNT) + dp->val.i32 = (PRUint32) gprData[iCount++]; + else + dp->val.i32 = (PRUint32) *ap++; + break; + + case nsXPTType::T_U64 : +#if 0 + if (iCount < PARAM_GPR_COUNT) + dp->val.i64.hi = (PRUint32) gprData[iCount++]; + else + dp->val.i64.hi = (PRUint32) *ap++; + if (iCount < PARAM_GPR_COUNT) + dp->val.i64.lo = (PRUint32) gprData[iCount++]; + else + dp->val.i64.lo = (PRUint32) *ap++; +#endif + { + PRUint64 tempu64; + if (iCount & 1) iCount++; // longlongs are aligned in odd/even register pairs, eg. r5/r6 + if ((iCount + 1) < PARAM_GPR_COUNT) { + tempu64 = *(PRUint64*) &gprData[iCount]; + iCount += 2; + } + else { + if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack + tempu64 = *(PRUint64*) ap; + ap += 2; + } + dp->val.i64 = (PRUint64)tempu64; + } + break; + case nsXPTType::T_FLOAT : if (fpCount < 13) { + dp->val.f = (float) fprData[fpCount++]; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + } + else + dp->val.f = *((float*) ap++); + break; + case nsXPTType::T_DOUBLE : if (fpCount < 13) { + dp->val.d = (double) fprData[fpCount++]; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + if (iCount < PARAM_GPR_COUNT) + ++iCount; + else + ++ap; + } + else { + dp->val.f = *((double*) ap); + ap += 2; + } + break; + case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT) + dp->val.b = (PRBool) gprData[iCount++]; + else + dp->val.b = (PRBool) *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->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + + +#define STUB_ENTRY(n) +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_netbsd.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_netbsd.cpp new file mode 100644 index 00000000..cbed6041 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_netbsd.cpp @@ -0,0 +1,146 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if defined(sparc) || defined(__sparc__) + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, uint32* args) +{ + + typedef struct { + uint32 hi; + uint32 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 = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* 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 = *((PRInt32*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt32*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) 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 = *((PRUint32*) ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint32*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_FLOAT : dp->val.f = *((float*) ap); break; + case nsXPTType::T_BOOL : dp->val.b = *((PRBool*) ap); break; + case nsXPTType::T_CHAR : dp->val.c = *((PRUint32*) ap); break; + case nsXPTType::T_WCHAR : dp->val.wc = *((PRInt32*) ap); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int 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_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#endif /* sparc || __sparc__ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_solaris.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_solaris.cpp new file mode 100644 index 00000000..cbed6041 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_solaris.cpp @@ -0,0 +1,146 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if defined(sparc) || defined(__sparc__) + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, uint32* args) +{ + + typedef struct { + uint32 hi; + uint32 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 = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* 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 = *((PRInt32*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt32*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) 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 = *((PRUint32*) ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint32*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_FLOAT : dp->val.f = *((float*) ap); break; + case nsXPTType::T_BOOL : dp->val.b = *((PRBool*) ap); break; + case nsXPTType::T_CHAR : dp->val.c = *((PRUint32*) ap); break; + case nsXPTType::T_WCHAR : dp->val.wc = *((PRInt32*) ap); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int 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_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#endif /* sparc || __sparc__ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparcv9_solaris.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparcv9_solaris.cpp new file mode 100644 index 00000000..f64b309e --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparcv9_solaris.cpp @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if defined(sparc) || defined(__sparc__) + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint64 methodIndex, PRUint64* args) +{ + +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint64* 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 = *((PRInt32*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt32*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) ap); break; + case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*) ap); break; + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); break; + case nsXPTType::T_U8 : dp->val.u8 = *((PRUint32*) ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint32*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_FLOAT : dp->val.f = *((float*) ap); break; + case nsXPTType::T_BOOL : dp->val.b = *((PRBool*) ap); break; + case nsXPTType::T_CHAR : dp->val.c = *((PRUint32*) ap); break; + case nsXPTType::T_WCHAR : dp->val.wc = *((PRInt32*) ap); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int 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_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#endif /* sparc || __sparc__ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unixish_x86.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unixish_x86.cpp new file mode 100644 index 00000000..91c5c5db --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unixish_x86.cpp @@ -0,0 +1,188 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" +#include "xptc_platforms_unixish_x86.h" +/*#include "xptiprivate.h"*/ + +static nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args) +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info = NULL; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + if (!iface_info) + return NS_ERROR_UNEXPECTED; + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no method info"); + if (!info) + return NS_ERROR_UNEXPECTED; + + 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"); + if (!dispatchParams) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32* 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 + dp->val.p = (void*) *ap; + switch(type) + { + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)ap); ap++; break; + case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); ap++; break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#ifdef __GNUC__ /* Gnu Compiler. */ + +#ifdef KEEP_STACK_16_BYTE_ALIGNED +/* Make sure the stack is 16-byte aligned. Do that by aligning to 16 bytes and + * then subtracting 4 so the three subsequent pushes result in a 16-byte aligned + * stack. */ +#define ALIGN_STACK_DECL \ + unsigned int saved_esp = 0; /* VBOX: Initialize it to shut up half a million gcc warnings on darwin. + * ALIGN_STACK_REGS_OUT/IN are a bit bogus, so the warning is probably correct. */ + +#define ALIGN_STACK_SAVE \ + "movl %%esp, %3\n\t" + +#define ALIGN_STACK_ALIGN \ + "addl $0x4, %%esp\n\t" \ + "andl $0xfffffff0, %%esp\n\t" \ + "subl $0x4, %%esp\n\t" + +#define STACK_RESTORE \ + "movl %3, %%esp\n" + +#define ALIGN_STACK_REGS_IN \ + , "=r"(saved_esp) /* 3 */ + +#define ALIGN_STACK_REGS_OUT \ + , "3"(saved_esp) + +#else +#define ALIGN_STACK_DECL +#define ALIGN_STACK_SAVE +#define ALIGN_STACK_ALIGN +#define STACK_RESTORE \ + "addl $12, %%esp\n" +#define ALIGN_STACK_REGS_IN +#define ALIGN_STACK_REGS_OUT +#endif + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + register nsresult (*method) (nsXPTCStubBase *, uint32, PRUint32 *) = PrepareAndDispatch; \ + int temp0, temp1; \ + register nsresult result; \ + ALIGN_STACK_DECL \ + __asm__ __volatile__( \ + ALIGN_STACK_SAVE \ + ALIGN_STACK_ALIGN \ + "leal 0x0c(%%ebp), %%ecx\n\t" /* args */ \ + "pushl %%ecx\n\t" \ + "pushl $"#n"\n\t" /* method index */ \ + "movl 0x08(%%ebp), %%ecx\n\t" /* this */ \ + "pushl %%ecx\n\t" \ + "call *%%edx\n\t" /* PrepareAndDispatch */ \ + STACK_RESTORE /* "addl $12, %%esp" or restore saved */ \ + : "=a" (result), /* %0 */ \ + "=&c" (temp0), /* %1 */ \ + "=d" (temp1) /* %2 */ \ + ALIGN_STACK_REGS_IN \ + : "2" (method) /* %2 */ \ + ALIGN_STACK_REGS_OUT \ + : "memory" \ + ); \ + return result; \ +} + +#else +#error "can't find a compiler to use" +#endif /* __GNUC__ */ + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unsupported.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unsupported.cpp new file mode 100644 index 00000000..0eea6567 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unsupported.cpp @@ -0,0 +1,56 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Stub called on unsupported platform"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp new file mode 100644 index 00000000..3381c48e --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp @@ -0,0 +1,242 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org Code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Implement shared vtbl methods. + +#include "xptcprivate.h" + +// The Linux/x86-64 ABI passes the first 6 integer parameters and the +// first 8 floating point parameters in registers (rdi, rsi, rdx, rcx, +// r8, r9 and xmm0-xmm7), no stack space is allocated for these by the +// caller. The rest of the parameters are passed in the callers stack +// area. + +const PRUint32 PARAM_BUFFER_COUNT = 16; +const PRUint32 GPR_COUNT = 6; +const PRUint32 FPR_COUNT = 8; + +// PrepareAndDispatch() is called by SharedStub() and calls the actual method. +// +// - 'args[]' contains the arguments passed on stack +// - 'gpregs[]' contains the arguments passed in integer registers +// - 'fpregs[]' contains the arguments passed in floating point registers +// +// The parameters are mapped into an array of type 'nsXPTCMiniVariant' +// and then the method gets called. + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase * self, PRUint32 methodIndex, + PRUint64 * args, PRUint64 * gpregs, double *fpregs) +{ + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info = NULL; + PRUint32 paramCount; + PRUint32 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + if (!iface_info) + return NS_ERROR_UNEXPECTED; + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no method info"); + if (!info) + return NS_ERROR_UNEXPECTED; + + 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"); + if (!dispatchParams) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint64* ap = args; + PRUint32 nr_gpr = 1; // skip one GPR register for 'that' + PRUint32 nr_fpr = 0; + PRUint64 value; + + 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 == nsXPTType::T_DOUBLE) { + if (nr_fpr < FPR_COUNT) + dp->val.d = fpregs[nr_fpr++]; + else + dp->val.d = *(double*) ap++; + continue; + } + else if (!param.IsOut() && type == nsXPTType::T_FLOAT) { + if (nr_fpr < 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*) ap++; + else + dp->val.f = *(float*) ap++; + continue; + } + else { + if (nr_gpr < GPR_COUNT) + value = gpregs[nr_gpr++]; + else + value = *ap++; + } + + if (param.IsOut() || !type.IsArithmetic()) { + dp->val.p = (void*) value; + continue; + } + + switch (type) { + case nsXPTType::T_I8: dp->val.i8 = (PRInt8) value; break; + case nsXPTType::T_I16: dp->val.i16 = (PRInt16) value; break; + case nsXPTType::T_I32: dp->val.i32 = (PRInt32) value; break; + case nsXPTType::T_I64: dp->val.i64 = (PRInt64) value; break; + case nsXPTType::T_U8: dp->val.u8 = (PRUint8) value; break; + case nsXPTType::T_U16: dp->val.u16 = (PRUint16) value; break; + case nsXPTType::T_U32: dp->val.u32 = (PRUint32) value; break; + case nsXPTType::T_U64: dp->val.u64 = (PRUint64) value; break; + case nsXPTType::T_BOOL: dp->val.b = (PRBool) value; break; + case nsXPTType::T_CHAR: dp->val.c = (char) value; break; + case nsXPTType::T_WCHAR: dp->val.wc = (wchar_t) value; break; + + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if (dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ +// Linux/x86-64 uses gcc >= 3.1 +#define STUB_ENTRY(n) \ +asm(".section \".text\"\n\t" \ + ".align 2\n\t" \ + ".if " #n " < 10\n\t" \ + ".globl _ZN14nsXPTCStubBase5Stub" #n "Ev\n\t" \ + ".type _ZN14nsXPTCStubBase5Stub" #n "Ev,@function\n" \ + "_ZN14nsXPTCStubBase5Stub" #n "Ev:\n\t" \ + ".elseif " #n " < 100\n\t" \ + ".globl _ZN14nsXPTCStubBase6Stub" #n "Ev\n\t" \ + ".type _ZN14nsXPTCStubBase6Stub" #n "Ev,@function\n" \ + "_ZN14nsXPTCStubBase6Stub" #n "Ev:\n\t" \ + ".elseif " #n " < 1000\n\t" \ + ".globl _ZN14nsXPTCStubBase7Stub" #n "Ev\n\t" \ + ".type _ZN14nsXPTCStubBase7Stub" #n "Ev,@function\n" \ + "_ZN14nsXPTCStubBase7Stub" #n "Ev:\n\t" \ + ".else\n\t" \ + ".err \"stub number " #n " >= 1000 not yet supported\"\n\t" \ + ".endif\n\t" \ + "movl $" #n ", %eax\n\t" \ + "jmp SharedStub\n\t" \ + ".if " #n " < 10\n\t" \ + ".size _ZN14nsXPTCStubBase5Stub" #n "Ev,.-_ZN14nsXPTCStubBase5Stub" #n "Ev\n\t" \ + ".elseif " #n " < 100\n\t" \ + ".size _ZN14nsXPTCStubBase6Stub" #n "Ev,.-_ZN14nsXPTCStubBase6Stub" #n "Ev\n\t" \ + ".else\n\t" \ + ".size _ZN14nsXPTCStubBase7Stub" #n "Ev,.-_ZN14nsXPTCStubBase7Stub" #n "Ev\n\t" \ + ".endif"); + +// static nsresult SharedStub(PRUint32 methodIndex) +asm(".section \".text\"\n\t" + ".align 2\n\t" + ".type SharedStub,@function\n\t" + "SharedStub:\n\t" + // make room for gpregs (48), fpregs (64) + "pushq %rbp\n\t" + "movq %rsp,%rbp\n\t" + "subq $112,%rsp\n\t" + // save GP registers + "movq %rdi,-112(%rbp)\n\t" + "movq %rsi,-104(%rbp)\n\t" + "movq %rdx, -96(%rbp)\n\t" + "movq %rcx, -88(%rbp)\n\t" + "movq %r8 , -80(%rbp)\n\t" + "movq %r9 , -72(%rbp)\n\t" + "leaq -112(%rbp),%rcx\n\t" + // save FP registers + "movsd %xmm0,-64(%rbp)\n\t" + "movsd %xmm1,-56(%rbp)\n\t" + "movsd %xmm2,-48(%rbp)\n\t" + "movsd %xmm3,-40(%rbp)\n\t" + "movsd %xmm4,-32(%rbp)\n\t" + "movsd %xmm5,-24(%rbp)\n\t" + "movsd %xmm6,-16(%rbp)\n\t" + "movsd %xmm7, -8(%rbp)\n\t" + "leaq -64(%rbp),%r8\n\t" + // rdi has the 'self' pointer already + "movl %eax,%esi\n\t" + "leaq 16(%rbp),%rdx\n\t" + "call PrepareAndDispatch@plt\n\t" + "leave\n\t" + "ret\n\t" + ".size SharedStub,.-SharedStub"); + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#else +#error "Unsupported compiler. Use gcc >= 3.1 for Linux/x86-64." +#endif /* __GNUC__ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_solaris.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_solaris.cpp new file mode 100644 index 00000000..59e0202f --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_solaris.cpp @@ -0,0 +1,271 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org Code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Implement shared vtbl methods. + +#include "xptcprivate.h" + +// The Linux/x86-64 ABI passes the first 6 integer parameters and the +// first 8 floating point parameters in registers (rdi, rsi, rdx, rcx, +// r8, r9 and xmm0-xmm7), no stack space is allocated for these by the +// caller. The rest of the parameters are passed in the callers stack +// area. +// Solaris does the same, just the assembler may differ. + +const PRUint32 PARAM_BUFFER_COUNT = 16; +const PRUint32 GPR_COUNT = 6; +const PRUint32 FPR_COUNT = 8; + +// PrepareAndDispatch() is called by SharedStub() and calls the actual method. +// +// - 'args[]' contains the arguments passed on stack +// - 'gpregs[]' contains the arguments passed in integer registers +// - 'fpregs[]' contains the arguments passed in floating point registers +// +// The parameters are mapped into an array of type 'nsXPTCMiniVariant' +// and then the method gets called. + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase * self, PRUint32 methodIndex, + PRUint64 * args, PRUint64 * gpregs, double *fpregs) +{ + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint32 paramCount; + PRUint32 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + if (!iface_info) + return NS_ERROR_UNEXPECTED; + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no method info"); + if (!info) + return NS_ERROR_UNEXPECTED; + + 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"); + if (!dispatchParams) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint64* ap = args; + PRUint32 nr_gpr = 1; // skip one GPR register for 'that' + PRUint32 nr_fpr = 0; + PRUint64 value; + + 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 == nsXPTType::T_DOUBLE) { + if (nr_fpr < FPR_COUNT) + dp->val.d = fpregs[nr_fpr++]; + else + dp->val.d = *(double*) ap++; + continue; + } + else if (!param.IsOut() && type == nsXPTType::T_FLOAT) { + if (nr_fpr < 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*) ap++; + else + dp->val.f = *(float*) ap++; + continue; + } + else { + if (nr_gpr < GPR_COUNT) + value = gpregs[nr_gpr++]; + else + value = *ap++; + } + + if (param.IsOut() || !type.IsArithmetic()) { + dp->val.p = (void*) value; + continue; + } + + switch (type) { + case nsXPTType::T_I8: dp->val.i8 = (PRInt8) value; break; + case nsXPTType::T_I16: dp->val.i16 = (PRInt16) value; break; + case nsXPTType::T_I32: dp->val.i32 = (PRInt32) value; break; + case nsXPTType::T_I64: dp->val.i64 = (PRInt64) value; break; + case nsXPTType::T_U8: dp->val.u8 = (PRUint8) value; break; + case nsXPTType::T_U16: dp->val.u16 = (PRUint16) value; break; + case nsXPTType::T_U32: dp->val.u32 = (PRUint32) value; break; + case nsXPTType::T_U64: dp->val.u64 = (PRUint64) value; break; + case nsXPTType::T_BOOL: dp->val.b = (PRBool) value; break; + case nsXPTType::T_CHAR: dp->val.c = (char) value; break; + case nsXPTType::T_WCHAR: dp->val.wc = (wchar_t) value; break; + + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if (dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#include <iprt/cdefs.h> + +#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ +// Solaris/x86-64 uses gcc >= 3.1 +#define STUB_ENTRY(n,m) \ +asm(".section .text\n\t" \ + ".align 2\n\t" \ + ".globl _ZN14nsXPTCStubBase" #m "Stub" #n "Ev\n\t" \ + ".type _ZN14nsXPTCStubBase" #m "Stub" #n "Ev,@function\n" \ + "_ZN14nsXPTCStubBase" #m "Stub" #n "Ev:\n\t" \ + "movl $" #n ", %eax\n\t" \ + "jmp SharedStub\n\t" \ + ".size _ZN14nsXPTCStubBase" #m "Stub" #n "Ev,.-_ZN14nsXPTCStubBase" #m "Stub" #n "Ev\n\t" \ + ) + +#define STUB_ENTRY_10(n10,m) \ + STUB_ENTRY(n10##0,m); \ + STUB_ENTRY(n10##1,m); \ + STUB_ENTRY(n10##2,m); \ + STUB_ENTRY(n10##3,m); \ + STUB_ENTRY(n10##4,m); \ + STUB_ENTRY(n10##5,m); \ + STUB_ENTRY(n10##6,m); \ + STUB_ENTRY(n10##7,m); \ + STUB_ENTRY(n10##8,m); \ + STUB_ENTRY(n10##9,m) +STUB_ENTRY_10(,5); +STUB_ENTRY_10(1,6); +STUB_ENTRY_10(2,6); +STUB_ENTRY_10(3,6); +STUB_ENTRY_10(4,6); +STUB_ENTRY_10(5,6); +STUB_ENTRY_10(6,6); +STUB_ENTRY_10(7,6); +STUB_ENTRY_10(8,6); +STUB_ENTRY_10(9,6); +STUB_ENTRY_10(10,7); +STUB_ENTRY_10(11,7); +STUB_ENTRY_10(12,7); +STUB_ENTRY_10(13,7); +STUB_ENTRY_10(14,7); +STUB_ENTRY_10(15,7); +STUB_ENTRY_10(16,7); +STUB_ENTRY_10(17,7); +STUB_ENTRY_10(18,7); +STUB_ENTRY_10(19,7); +STUB_ENTRY_10(20,7); +STUB_ENTRY_10(21,7); +STUB_ENTRY_10(22,7); +STUB_ENTRY_10(23,7); +STUB_ENTRY_10(24,7); + + +// static nsresult SharedStub(PRUint32 methodIndex) +asm(".section .text\n\t" + ".align 2\n\t" + ".type SharedStub,@function\n\t" + "SharedStub:\n\t" + // make room for gpregs (48), fpregs (64) + "pushq %rbp\n\t" + "movq %rsp,%rbp\n\t" + "subq $112,%rsp\n\t" + // save GP registers + "movq %rdi,-112(%rbp)\n\t" + "movq %rsi,-104(%rbp)\n\t" + "movq %rdx, -96(%rbp)\n\t" + "movq %rcx, -88(%rbp)\n\t" + "movq %r8 , -80(%rbp)\n\t" + "movq %r9 , -72(%rbp)\n\t" + "leaq -112(%rbp),%rcx\n\t" + // save FP registers + "movsd %xmm0,-64(%rbp)\n\t" + "movsd %xmm1,-56(%rbp)\n\t" + "movsd %xmm2,-48(%rbp)\n\t" + "movsd %xmm3,-40(%rbp)\n\t" + "movsd %xmm4,-32(%rbp)\n\t" + "movsd %xmm5,-24(%rbp)\n\t" + "movsd %xmm6,-16(%rbp)\n\t" + "movsd %xmm7, -8(%rbp)\n\t" + "leaq -64(%rbp),%r8\n\t" + // rdi has the 'self' pointer already + "movl %eax,%esi\n\t" + "leaq 16(%rbp),%rdx\n\t" + "call PrepareAndDispatch@plt\n\t" + "leave\n\t" + "ret\n\t" + ".size SharedStub,.-SharedStub"); + + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +SENTINEL_ENTRY(0) +SENTINEL_ENTRY(1) +SENTINEL_ENTRY(2) +SENTINEL_ENTRY(3) +SENTINEL_ENTRY(4) + +#else +#error "Unsupported compiler. Use gcc >= 3.1 for Linux/x86-64." +#endif /* __GNUC__ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_solaris.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_solaris.cpp new file mode 100644 index 00000000..d4ae7667 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_solaris.cpp @@ -0,0 +1,165 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org Code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" +#include "xptc_platforms_unixish_x86.h" + +static nsresult +PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args) +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info = NULL; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + if (!iface_info) + return NS_ERROR_UNEXPECTED; + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no method info"); + if (!info) + return NS_ERROR_UNEXPECTED; + + 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"); + if (!dispatchParams) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32* 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 + dp->val.p = (void*) *ap; + switch(type) + { + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)ap); ap++; break; + case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); ap++; break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +#ifdef __GNUC__ /* Gnu Compiler. */ +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + register nsresult (*method) (nsXPTCStubBase *, uint32, PRUint32 *) = PrepareAndDispatch; \ + int temp0, temp1; \ + register nsresult result; \ + __asm__ __volatile__( \ + "leal 0x0c(%%ebp), %%ecx\n\t" /* args */ \ + "pushl %%ecx\n\t" \ + "pushl $"#n"\n\t" /* method index */ \ + "movl 0x08(%%ebp), %%ecx\n\t" /* this */ \ + "pushl %%ecx\n\t" \ + "call *%%edx\n\t" /* PrepareAndDispatch */ \ + "addl $12, %%esp" \ + : "=a" (result), /* %0 */ \ + "=&c" (temp0), /* %1 */ \ + "=d" (temp1) /* %2 */ \ + : "2" (method) /* %2 */ \ + : "memory" ); \ + return result; \ +} + +#elif defined(__SUNPRO_CC) /* Sun Workshop Compiler. */ + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + asm ( \ + "\n\t leal 0x0c(%ebp), %ecx\t / args" \ + "\n\t pushl %ecx" \ + "\n\t pushl $"#n"\t / method index" \ + "\n\t movl 0x08(%ebp), %ecx\t / this" \ + "\n\t pushl %ecx" \ + "\n\t call __1cSPrepareAndDispatch6FpnOnsXPTCStubBase_IpI_I_\t / PrepareAndDispatch" \ + "\n\t addl $12, %esp" \ + ); \ +/* result == %eax */ \ + if(0) /* supress "*** is expected to return a value." error */ \ + return 0; \ +} + +#else +#error "can't find a compiler to use" +#endif /* __GNUC__ */ + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/Makefile.in new file mode 100644 index 00000000..0de74ee2 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/Makefile.in @@ -0,0 +1,82 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +LIBRARY_NAME = xptcmd + +# +# The default is this buildable, but non-functioning code. +# +ifdef GNU_CXX +CPPSRCS = \ + ../unix/xptcinvoke_gcc_x86_unix.cpp \ + xptcstubs.cpp \ + $(NULL) +LOCAL_INCLUDES = -I$(srcdir)/../unix +DEFINES += -DMOZ_USE_STDCALL -DMOZ_NEED_LEADING_UNDERSCORE +else +CPPSRCS = xptcinvoke.cpp xptcstubs.cpp +endif + + +# Force use of PIC +FORCE_USE_PIC = 1 + +include $(topsrcdir)/config/config.mk + +ifeq ($(CPU),ALPHA) +CPPSRCS := xptcinvoke_alpha.cpp xptcstubs_alpha.cpp +ASFILES := xptcinvoke_asm_alpha.s xptcstubs_asm_alpha.s +AS := asaxp +ASFLAGS += /I../../..public +endif + +# we don't want the shared lib, but we want to force the creation of a static lib. +FORCE_STATIC_LIB = 1 + +include $(topsrcdir)/config/rules.mk + +DEFINES += -DEXPORT_XPTC_API -D_IMPL_NS_COM -D_IMPL_NS_BASE + +LOCAL_INCLUDES += -I$(srcdir)/../.. diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcinvoke.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcinvoke.cpp new file mode 100644 index 00000000..9fbf2f94 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcinvoke.cpp @@ -0,0 +1,107 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +#ifndef WIN32 +#error "This code is for Win32 only" +#endif + +static void __fastcall +invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s) +{ + for(; paramCount > 0; paramCount--, d++, s++) + { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : *((PRInt8*) d) = s->val.i8; break; + case nsXPTType::T_I16 : *((PRInt16*) d) = s->val.i16; break; + case nsXPTType::T_I32 : *((PRInt32*) d) = s->val.i32; break; + case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_U8 : *((PRUint8*) d) = s->val.u8; break; + case nsXPTType::T_U16 : *((PRUint16*)d) = s->val.u16; break; + case nsXPTType::T_U32 : *((PRUint32*)d) = s->val.u32; break; + case nsXPTType::T_U64 : *((PRUint64*)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 : *((PRBool*) 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; + } + } +} + +#pragma warning(disable : 4035) // OK to have no return value +__declspec(naked) XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + __asm { + push ebp + mov ebp,esp + mov edx,paramCount // Save paramCount for later + test edx,edx // maybe we don't have any params to copy + jz noparams + mov eax,edx + shl eax,3 // *= 8 (max possible param size) + sub esp,eax // make space for params + mov ecx,esp + push params + call invoke_copy_to_stack // fastcall, ecx = d, edx = paramCount, params is on the stack +noparams: + mov ecx,that // instance in ecx + push ecx // push this + mov edx,[ecx] // vtable in edx + mov eax,methodIndex + call [edx][eax*4] // stdcall, i.e. callee cleans up stack. + mov esp,ebp + pop ebp + ret + } +} +#pragma warning(default : 4035) // restore default diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcinvoke_alpha.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcinvoke_alpha.cpp new file mode 100644 index 00000000..06334ac0 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcinvoke_alpha.cpp @@ -0,0 +1,171 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +/* contributed by bob meader <bob@guiduck.com> */ + +#include "xptcprivate.h" + +extern "C" uint32 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s) +{ + return(paramCount*2); +} + +extern "C" void +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, + nsXPTCVariant* s, PRUint64 *regs) +{ +#define N_ARG_REGS 5 /* 6 regs minus 1 for "this" ptr */ + + for (PRUint32 i = 0; i < paramCount; i++, s++) + { + if (s->IsPtrData()) { + if (i < N_ARG_REGS) + regs[i] = (PRUint32)s->ptr; + else + *((PRUint32*)d++) = (PRUint32)s->ptr; + continue; + } + switch (s->type) { + // + // signed types first + // + case nsXPTType::T_I8: + if (i < N_ARG_REGS) + ((PRInt64*)regs)[i] = s->val.i8; + else + *((PRInt8 *)d++) = s->val.i8; + break; + case nsXPTType::T_I16: + if (i < N_ARG_REGS) + ((PRInt64*)regs)[i] = s->val.i16; + else + *((PRInt16 *)d++) = s->val.i16; + break; + case nsXPTType::T_I32: + if (i < N_ARG_REGS) + ((PRInt64*)regs)[i] = s->val.i32; + else + *((PRUint32*)d++) = s->val.i32; + break; + case nsXPTType::T_I64: + if (i < N_ARG_REGS) + ((PRInt64*)regs)[i] = s->val.i64; + else + *((PRInt64*)d++) = s->val.i64; + break; + // + // unsigned types next + // + case nsXPTType::T_U8: + if (i < N_ARG_REGS) + regs[i] = s->val.u8; + else + *((PRUint8 *)d++) = s->val.u8; + break; + case nsXPTType::T_U16: + if (i < N_ARG_REGS) + regs[i] = s->val.u16; + else + *((PRUint16 *)d++) = s->val.u16; + break; + case nsXPTType::T_U32: + if (i < N_ARG_REGS) + regs[i] = s->val.u32; + else + *((PRUint32*)d++) = s->val.u32; + break; + case nsXPTType::T_U64: + if (i < N_ARG_REGS) + regs[i] = s->val.u64; + else + *((PRUint64*)d++) = s->val.u64; + break; + case nsXPTType::T_FLOAT: + if (i < N_ARG_REGS) + ((double*)regs)[i] = s->val.f; + else + *((float*)d++) = s->val.f; + break; + case nsXPTType::T_DOUBLE: + if (i < N_ARG_REGS) + ((double*)regs)[i] = s->val.d; + else + *((double*)d++) = s->val.d; + break; + case nsXPTType::T_BOOL: + if (i < N_ARG_REGS) + regs[i] = s->val.b; + else + *((PRBool*)d++) = s->val.b; + break; + case nsXPTType::T_CHAR: + if (i < N_ARG_REGS) + regs[i] = s->val.c; + else + *((char*)d++) = s->val.c; + break; + case nsXPTType::T_WCHAR: + if (i < N_ARG_REGS) + regs[i] = s->val.wc; + else + *((wchar_t*)d++) = s->val.wc; + break; + default: + // all the others are plain pointer types + if (i < N_ARG_REGS) + regs[i] = (PRUint32)s->val.p; + else + *((PRUint32*)d++) = (PRUint32)s->val.p; + break; + } + } +} + +extern "C" nsresult XPTC__InvokebyIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +extern "C" +XPTC_PUBLIC_API(nsresult) +XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params) +{ + return XPTC__InvokebyIndex(that, methodIndex, paramCount, params); +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcinvoke_asm_alpha.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcinvoke_asm_alpha.s new file mode 100644 index 00000000..7f8b343b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcinvoke_asm_alpha.s @@ -0,0 +1,128 @@ +.text +.globl invoke_count_words +.globl invoke_copy_to_stack + +#define v0 $0 +#define t0 $1 +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define s0 $9 +#define fp $15 +#define a0 $16 +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 +#define t9 $23 +#define ra $26 +#define gp $29 +#define sp $30 +#define zero $31 +#define f0 $f0 + +#define LOCALSZ 7 +#define NARG 2 +#define SZREG 8 +#define FRAMESZ ((NARG+LOCALSZ)*SZREG) +RAOFF=FRAMESZ-(1*SZREG) +A0OFF=FRAMESZ-(2*SZREG) +A1OFF=FRAMESZ-(3*SZREG) +A2OFF=FRAMESZ-(4*SZREG) +A3OFF=FRAMESZ-(5*SZREG) +S0OFF=FRAMESZ-(6*SZREG) +GPOFF=FRAMESZ-(7*SZREG) + +// +// Nested +// XPTC__InvokebyIndex( that, methodIndex, paramCount, params) +// a0 a1 a2 a3 +// + .text + .align 4 + .globl XPTC__InvokebyIndex + .ent XPTC__InvokebyIndex,0 +XPTC__InvokebyIndex: + .frame sp, FRAMESZ, ra + subl sp,FRAMESZ,sp // allocate stack space for structure + stq ra, RAOFF(sp) + stq a0, A0OFF(sp) + stq a1, A1OFF(sp) + stq a2, A2OFF(sp) + stq a3, A3OFF(sp) + stq s0, S0OFF(sp) +// stq gp, GPOFF(sp) Don't think I am to save gp + + // invoke_count_words(paramCount, params) + bis a2,zero,a0 // move a2 into a0 + bis a3,zero,a1 // move a3 into a1 + bsr ra,invoke_count_words + + // invoke_copy_to_stack + ldq a1, A2OFF(sp) // a1 = paramCount + ldq a2, A3OFF(sp) // a2 = params + + // save sp before we copy the params to the stack + bis sp,zero,t0 // t0 = sp + + // assume full size of 8 bytes per param to be safe + sll v0,4,v0 //v0 = 8 bytes * num params + subl sp,v0,sp //sp = sp - v0 + bis sp,zero,a0 //a0 = param stack address + + // create temporary stack space to write int and fp regs + subl sp,64,sp //sp = sp -64 // (64 = 8 regs of eight bytes) + bis sp,zero,a3 // a3 = sp + + // save the old sp and save the arg stack + subl sp,16,sp //sp = sp -16 + stq t0,0(sp) + stq a0,8(sp) + // copy the param into the stack areas + bsr ra,invoke_copy_to_stack + + ldq t3,8(sp) // get previous a0 + ldq sp,0(sp) // get orig sp back + + ldq a0,A0OFF(sp) // a0 = that + ldq a1,A1OFF(sp) // a1 = methodIndex + + // calculate jmp address from method index + ldl t1,0(a0) // t1 = *that + sll a1,2,a1 // a1 = 4*index + addl t1,a1,t9 + ldl t9,0(t9) // t9=*(that + 4*index) + + // get register save area from invoke_copy_to_stack + subl t3,64,t1 + + // a1..a5 and f17..f21 should now be set to what + // invoke_copy_to_stack told us. skip a0 and f16 + // because that's the "this" pointer + + ldq a1,0(t1) + ldq a2,8(t1) + ldq a3,16(t1) + ldq a4,24(t1) + ldq a5,32(t1) + + ldt $f17,0(t1) + ldt $f18,8(t1) + ldt $f19,16(t1) + ldt $f20,24(t1) + ldt $f21,32(t1) + + // save away our stack point and create + // the stack pointer for the function + bis sp,zero,s0 + bis t3,zero,sp + jsr ra,(t9) + bis s0,zero,sp + ldq ra,RAOFF(sp) + ldq s0,S0OFF(sp) + addl sp,FRAMESZ,sp + ret + +.end XPTC__InvokebyIndex + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp new file mode 100644 index 00000000..bd5ab975 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp @@ -0,0 +1,202 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#ifndef WIN32 +#error "This code is for Win32 only" +#endif + +extern "C" { + +static nsresult __stdcall +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, + PRUint32* args, PRUint32* stackBytesToPop) +{ +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info = NULL; + PRUint8 paramCount; + PRUint8 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->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint32* 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 = *((PRInt8*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt16*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) ap); break; + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break; + case nsXPTType::T_U8 : dp->val.u8 = *((PRUint8*) ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint16*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*)ap); break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)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 = *((PRBool*) 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_ASSERTION(0, "bad type"); + break; + } + } + *stackBytesToPop = ((PRUint32)ap) - ((PRUint32)args); + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +} // extern "C" + +// declspec(naked) is broken in gcc +#ifndef __GNUC__ +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 + +#define STUB_ENTRY(n) \ +nsresult __stdcall nsXPTCStubBase::Stub##n() \ +{ \ + PRUint32 *args, stackBytesToPop = 0; \ + nsresult result = 0; \ + nsXPTCStubBase *obj; \ + __asm__ __volatile__ ( \ + "leal 0x0c(%%ebp), %%ecx\n\t" /* args */ \ + "movl 0x08(%%ebp), %%edx\n\t" /* this */ \ + : "=c" (args), \ + "=d" (obj)); \ + result = PrepareAndDispatch(obj, n, args, &stackBytesToPop); \ + return result; \ +} + +#endif /* __GNUC__ */ + +#define SENTINEL_ENTRY(n) \ +nsresult __stdcall nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"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/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcstubs_alpha.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcstubs_alpha.cpp new file mode 100644 index 00000000..69a10e70 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcstubs_alpha.cpp @@ -0,0 +1,228 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +/* contributed by bob meader <bob@guiduck.com> */ + +/* + * This is for Alpha /NT 32 bits + * + * When we're called, the "gp" registers are stored in gprData and + * the "fp" registers are stored in fprData. There are 6 regs + * available which coorespond to the first 5 parameters of the + * function and the "this" pointer. If there are additional parms, + * they are stored on the stack at address "args". + * + */ +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint64* args, + PRUint64 *gprData, double *fprData) +{ +#define PARAM_BUFFER_COUNT 16 +#define PARAM_GPR_COUNT 5 +#define PARAM_FPR_COUNT 5 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(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"); + + PRUint64* ap = args; + PRUint32 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 = (PRInt8)gprData[iCount++]; + else + dp->val.i8 = *((PRInt8*)ap++); + break; + + case nsXPTType::T_I16: + if (iCount < PARAM_GPR_COUNT) + dp->val.i16 = (PRInt16)gprData[iCount++]; + else + dp->val.i16 = *((PRInt16*)ap++); + break; + + case nsXPTType::T_I32: + if (iCount < PARAM_GPR_COUNT) + dp->val.i32 = (PRInt32)gprData[iCount++]; + else + dp->val.i32 = *((PRInt32*)ap++); + break; + + case nsXPTType::T_I64: + if (iCount < PARAM_GPR_COUNT) + dp->val.i64 = (PRInt64)gprData[iCount++]; + else + dp->val.i64 = *((PRInt64*)ap++); + break; + + case nsXPTType::T_U8: + if (iCount < PARAM_GPR_COUNT) + dp->val.u8 = (PRUint8)gprData[iCount++]; + else + dp->val.u8 = *((PRUint8*)ap++); + break; + + case nsXPTType::T_U16: + if (iCount < PARAM_GPR_COUNT) + dp->val.u16 = (PRUint16)gprData[iCount++]; + else + dp->val.u16 = *((PRUint16*)ap++); + break; + + case nsXPTType::T_U32: + if (iCount < PARAM_GPR_COUNT) + dp->val.u32 = (PRUint32)gprData[iCount++]; + else + dp->val.u32 = *((PRUint32*)ap++); + break; + + case nsXPTType::T_U64: + if (iCount < PARAM_GPR_COUNT) + dp->val.u64 = (PRUint64)gprData[iCount++]; + else + dp->val.u64 = (PRUint64)*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 = (PRBool)gprData[iCount++]; + else + dp->val.b = *((PRBool*)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->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + 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_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +void +xptc_dummy() +{ +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcstubs_asm_alpha.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcstubs_asm_alpha.s new file mode 100644 index 00000000..5f8f861d --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/win32/xptcstubs_asm_alpha.s @@ -0,0 +1,120 @@ + +#define v0 $0 // return value register +#define t0 $1 // caller saved (temporary) registers +#define t1 $2 // +#define t2 $3 // +#define t3 $4 // +#define t4 $5 // +#define t5 $6 // +#define t6 $7 // +#define t7 $8 // +#define s0 $9 // callee saved (nonvolatile) registers +#define a0 $16 // argument registers +#define a1 $17 // +#define a2 $18 // +#define a3 $19 // +#define a4 $20 // +#define a5 $21 // +#define t8 $22 // caller saved (temporary) registers +#define t9 $23 // +#define t10 $24 // +#define t11 $25 // +#define ra $26 // return address register +#define sp $30 // stack pointer register +#define zero $31 // zero register +#define f16 $f16 // argument registers +#define f17 $f17 // +#define f18 $f18 // +#define f19 $f19 // +#define f20 $f20 // +#define f21 $f21 // + +#define NARGSAVE 2 +#define LOCALSZ 16 +#define SZREG 8 +#define FRAMESZ (NARGSAVE+LOCALSZ)*SZREG + + .text + .globl PrepareAndDispatch + +A1OFF=FRAMESZ-(9*SZREG) +A2OFF=FRAMESZ-(8*SZREG) +A3OFF=FRAMESZ-(7*SZREG) +A4OFF=FRAMESZ-(6*SZREG) +A5OFF=FRAMESZ-(5*SZREG) +A6OFF=FRAMESZ-(4*SZREG) //not used +A7OFF=FRAMESZ-(3*SZREG) //not used +GPOFF=FRAMESZ-(2*SZREG) //not used +RAOFF=FRAMESZ-(1*SZREG) + +F16OFF=FRAMESZ-(16*SZREG) //not used +F17OFF=FRAMESZ-(15*SZREG) +F18OFF=FRAMESZ-(14*SZREG) +F19OFF=FRAMESZ-(13*SZREG) +F20OFF=FRAMESZ-(12*SZREG) +F21OFF=FRAMESZ-(11*SZREG) +F22OFF=FRAMESZ-(10*SZREG) // not used + +#define NESTED_ENTRY(Name, fsize, retrg) \ + .text; \ + .align 4; \ + .globl Name; \ + .ent Name, 0; \ +Name:; \ + .frame sp, fsize, retrg; + +#define SENTINEL_ENTRY(nn) +#define STUB_ENTRY(nn) MAKE_PART(nn,@nsXPTCStubBase@@UAAIXZ ) + +#define MAKE_PART(aa, bb) MAKE_STUB(aa, ?Stub##aa##bb ) + +#define MAKE_STUB(nn, name) \ +NESTED_ENTRY(name, FRAMESZ,ra); \ + subl sp,FRAMESZ,sp; \ + mov nn,t0; \ + jmp sharedstub; \ +.end name; + +#include "xptcstubsdef.inc" + + .globl sharedstub + .ent sharedstub +sharedstub: + stq a1,A1OFF(sp) + stq a2,A2OFF(sp) + stq a3,A3OFF(sp) + stq a4,A4OFF(sp) + stq a5,A5OFF(sp) + stq ra,RAOFF(sp) + + stt f17,F17OFF(sp) + stt f18,F18OFF(sp) + stt f19,F19OFF(sp) + stt f20,F20OFF(sp) + stt f21,F21OFF(sp) + + // t0 is methodIndex + bis t0,zero,a1 // a1 = methodIndex + + // a2 is stack address where extra function params + // are stored that do not fit in registers + bis sp,zero,a2 //a2 = sp + addl a2,FRAMESZ,a2 //a2+=FRAMESZ + + // a3 is stack addrss of a1..a5 + bis sp,zero,a3 //a3 = sp + addl a3,A1OFF,a3 //a3+=A1OFF + + // a4 is stack address of f17..f21 + bis sp,zero,a4 //a4 = sp + addl a4,F17OFF,a4 //a4+=F17OFF + + // PrepareAndDispatch(that, methodIndex, args, gprArgs, fpArgs) + // a0 a1 a2 a3 a4 + bsr PrepareAndDispatch + ldq ra,RAOFF(sp) + addl sp,FRAMESZ,sp + ret + +.end sharedstub + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/xptcall.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/xptcall.cpp new file mode 100644 index 00000000..f25a94e5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/xptcall.cpp @@ -0,0 +1,62 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* entry point wrappers. */ + +#if defined(XP_MAC) +#pragma export on +#endif + +#include "xptcprivate.h" + +// This method is never called and is only here so the compiler +// will generate a vtbl for this class. +// *Needed by the Irix implementation.* +NS_IMETHODIMP nsXPTCStubBase::QueryInterface(REFNSIID aIID, + void** aInstancePtr) +{ + NS_ASSERTION(0,"wowa! nsXPTCStubBase::QueryInterface called"); + return NS_ERROR_FAILURE; +} +#if defined(XP_MAC) +#pragma export off +#endif + +void +xptc_dummy2() +{ +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/xptcprivate.h b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/xptcprivate.h new file mode 100644 index 00000000..3691fa0a --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/xptcprivate.h @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* All the xptcall private declarations - only include locally. */ + +#ifndef xptcprivate_h___ +#define xptcprivate_h___ + +#include "xptcall.h" + +#endif /* xptcprivate_h___ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/status.html b/src/libs/xpcom18a4/xpcom/reflect/xptcall/status.html new file mode 100644 index 00000000..e3686999 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/status.html @@ -0,0 +1,404 @@ +<html> +<head> +<title>xptcall Porting Status</title> +</head> +<body bgcolor = "white"> +<h2><center>xptcall Porting Status</center></h2> + +<h3>What is this?</h3> + +This is a status page for the multiplatform porting of xptcall. +xptcall has a +<a href="http://www.mozilla.org/scriptable/xptcall-faq.html">FAQ</a> +and a +<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/porting.html">Porting Guide</a>. + +<p> + +This is being maintained by <a href="mailto:jband@netscape.com">John Bandhauer <jband@netscape.com></a>. +Feel free to email me with questions or to volunteer to contribute xptcall code for any platform. + +<p> + +<a href="mailto:shaver@mozilla.org">Mike Shaver <shaver@mozilla.org></a> +is the best contact regarding 'nix (Unix, Linux, Finux, etc.) ports of xptcall. + +<h3>Status</h3> + +<table BORDER="1"> +<TR align="left" BGCOLOR="yellow"> +<TH>Status</TH> +<TH>Platform</TH> +<TH><img src="http://tinderbox.mozilla.org/star.gif">Contributors and <font color="red"><b>?</b></font> Possible Contributors</TH> +<TH>Notes</TH> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Win32 x86</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:jband@netscape.com">John Bandhauer <jband@netscape.com></a> +</TD> +<TD> +<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32">win32</a></TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Linux x86</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:jband@netscape.com">John Bandhauer <jband@netscape.com></a><br> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:drepper@cygnus.com">Ulrich Drepper <drepper@cygnus.com></a> +</TD> +<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>FreeBSD and NetBSD x86</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:toshok@hungry.com">Christoph Toshok <toshok@hungry.com></a>,<BR> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:jband@netscape.com">John Bandhauer <jband@netscape.com></a></TD> +<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> (same as Linux 86 code)</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>BSD/OS x86</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:bert_driehuis@nl.compuware.com">Bert Driehuis <bert_driehuis@nl.compuware.com></a></TD> +<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> (same as Linux 86 code) +Bert contributed patches that *should* do the right thing for all the unixish-x86 +versions of this code for GCC 2.7 or 2.8 vs. EGCS 1.1. He notes that the vtbl +scheme is different. He is hoping that others will help test the changes using +these two compilers on the various platforms where this same code is used. +<a href="news://news.mozilla.org/372DD257.4248C821%40nl.compuware.com">Bert's details</a> +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Mac PPC</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> + <a href="mailto:rogerl@netscape.com">Roger Lawrence <rogerl@netscape.com></a>,<BR> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:beard@netscape.com">Patrick Beard <beard@netscape.com></a> +</TD> +<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/mac">mac</a> (passing tests and checked in)</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Solaris Sparc</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:rogerl@netscape.com">Roger Lawrence <rogerl@netscape.com></a>,<BR> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:mcafee@netscape.com">Chris McAfee <mcafee@netscape.com></a> +</TD> +<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> This is checked in and working.</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Solaris Sparc v9 (64bit)</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:pavlov@netscape.com">Stuart Parmenter <pavlov@netscape.com></a>,<BR> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:cls@seawood.org">Chris Seawood <cls@seawood.org></a> +</TD> +<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> This is checked in and (pavlov claims!) working.</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>OS/2</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:mjf35@cam.ac.uk">John Fairhurst <mjf35@cam.ac.uk></a></TD> +<TD>I never heard exactly who did what. But mozilla has been working on OS/2 +for a long time now. +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>OpenVMS Alpha</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:colin@theblakes.com">Colin R. Blake <colin@theblakes.com></a></TD> +<TD> +Colin says this is passing all the tests on OpenVMS Alpha! +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>NT Alpha</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:bob@guiduck.com">bob meader <bob@guiduck.com></a></TD> +<TD> +bob writes:<br> +Enclosed is xptcall for alpha/nt target.. +<p> +It is a variation of the IRIS port (only targeted for win32). +<p> +Notice the last 2 files (the change to mozilla\xpcom\build\makefile.win and +mozilla\xpcom\build) are needed because I was unable to figure how to do a +"declspecexport" from the assembler ASAXP ... if some knows how to do that then +those last 2 files won't be needed. +<p> +I have had someone look over this code at bridge.com (the entry point to +compaq/gem compiler team) and this code was given the OK. I consider it "done". +<p> +This code lives in the files where the name includes 'alpha' in the <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32">win32</a> directory.<BR> +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Linux ARM</TD> +<TD><img alt="Started" title="Started" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:sh990154@mail.uni-greifswald.de">Stefan Hanske<sh990154@mail.uni-greifswald.de></a><BR> +<font color="red"><b>?</b></font> +<a href="mailto:willy@bofh.ai">Matthew Wilcox <willy@bofh.ai></a></TD> +<TD> +Stefan's code is checked in and he says it is working. +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Linux Sparc</TD> +<TD> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:anton@progsoc.uts.edu.au">Anton Blanchard <anton@progsoc.uts.edu.au></a>, +<BR> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:rogerl@netscape.com">Roger Lawrence <rogerl@netscape.com></a>, +<BR> +<img alt="Maybe" title="Maybe" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:ehle.3@osu.eduehle.3@osu.edu">Brandon Ehle <ehle.3@osu.edu></a> +</TD> +<TD> +Anton contributed patches to Roger's Sparc code. Anton says it works and passes the tests!<b> +(24-Aug-1999) Brandon writes: I've finished testing XPTCALL Sparc Linux on 12 different Sparc machines and it checks out good. +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Linux PPC</TD> +<TD> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:beard@netscape.com">Patrick Beard <beard@netscape.com></a><BR> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:waterson@netscape.com">Chris Waterson <waterson@netscape.com></a><BR> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:Franz.Sirl-kernel@lauterbach.com">Franz Sirl <Franz.Sirl-kernel@lauterbach.com></a><BR> +<font color="red"><b>?</b></font> +<a href="mailto:jsproul@condor.fddi.wesleyan.edu">Jason Y. Sproul <jsproul@condor.fddi.wesleyan.edu></a><BR> + <font color="red"><b>?</b></font> + <a href="mailto:darkmane@w-link.net">Sean Chitwood <darkmane@w-link.net></a></TD> +<TD> +waterson said: <b>Mozilla runs on Linux/PPC</b> +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Linux Alpha</TD> +<TD> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:glen.nakamura@usa.net">Glen Nakamura <glen.nakamura@usa.net></a><BR> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:morrildl@nycap.rr.com">Dan Morril <morrildl@nycap.rr.com></a><BR> +</TD> +<TD> +Glen writes: +<p> +I am attaching a patch which contains my Linux Alpha xptcall code. +It passes TestXPTCInvoke and TestXPC on my machine which runs +kernel 2.2.7, glibc 2.1.1, and egcs 1.1.2. I have not tested it +with older GNU compilers such as gcc 2.8.x. From looking at the +Linux x86 code, I gather that the vtable layout is a little different +for those compilers and the code will need minor modifications +in order to work properly. +<p> +I am not sure how much of the code can be used for OpenVMS Alpha +and/or Digital UNIX. Currently the code is dependent on the g++ +name mangling convention and a few GNU extensions so I'm not sure +how useful it will be for the other systems. Hopefully the +comments in the code are detailed enough to help people attempting +a port. +<p> +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>SunOS x86</TD> +<TD> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:aljones@lbl.gov">Arthur Jones <aljones@lbl.gov></a><BR> +<font color="red"><b>?</b></font> +<a href="mailto:ppokorny@mindspring.com">Philip Pokorny <ppokorny@mindspring.com></a><BR> +</TD> +<TD> +The word I hear is that this is working and done +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>HP-UX</TD> +<TD> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:wang@cup.hp.com">Thomas Wang <wang@cup.hp.com></a><BR> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:mgleeson1@netscape.com">Mike Gleeson <mgleeson1@netscape.com></a> +</TD> +<TD>I hear that this code is checked in and working. Though, there is some +doubt - see bug +#<a href="http://bugzilla.mozilla.org/show_bug.cgi?id=17997">17997</a> +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>AIX PPC</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:jdunn@netscape.com">Jim Dunn <jdunn@netscape.com></a></TD> +<TD>Philip K. Warren writes: <BR> + +We have gone through several releases of AIX without any problems. +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Irix</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:jasonh@m7.engr.sgi.com">Jason Heirtzler <jasonh@m7.engr.sgi.com></a><BR> +</TD> +<TD>Jason has declared this done. Jason is no longer working at SGI and will +not be maintaining this code. There is some doubt as to whether or not this is +working for everyone - see bug +#<a href="http://bugzilla.mozilla.org/show_bug.cgi?id=10061">10061</a>. +<a href="mailto:shaver@mozilla.org">Mike Shaver <shaver@mozilla.org></a> +is the interim maintainer until someone more suitable can be found. +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>BeOS x86</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:duncan@be.com">Duncan Wilcox <duncan@be.com></a><BR> +</TD> +<TD> +<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> (yet another reuse of the Linux 86 code!)<BR> +Duncan says this is all working. He did the code for old cfront style 'this' adjustment for others to use too! +</TD> +</TR> + +<TR> +<TD bgcolor="red"><font color="white"><b>HELP!</b></font></TD> +<TD>BeOS PPC</TD> +<TD align="center">-</TD> +<TD align="center">-</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>Compaq Tru64 UNIX (Digital UNIX)</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:streeter@zk3.dec.com">Steve Streeter <streeter@zk3.dec.com></a><BR> +</TD> +<TD>Code passes the tests and is checked in.</TD> +</TR> + +<TR> +<TD bgcolor="khaki"><font color="black"><b>Working</b></font></TD> +<TD>Neutrio x86</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:Jerry.Kirk@Nexwarecorp.com">Jerry L. Kirk <Jerry.Kirk@Nexwarecorp.com></a><BR> +</TD> +<TD> +Patches for xptc*_unixish_x86.cpp checked in. Waiting for verification that this is really finished. +</TD> +</TR> + +<TR> +<TD bgcolor="khaki"><font color="black"><b>Investigating</b></font></TD> +<TD>SCO UW7 and OSR5</TD> +<TD> +<img alt="Investigating" title="Investigating" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:jkj@sco.com">J. Kean Johnston <jkj@sco.com></a><BR> +<img alt="Investigating" title="Investigating" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:evanh@sco.com">Evan Hunt <evanh@sco.com></a><BR> +</TD> +<TD>Recent (Feb-2001) email from jkj@sco.com suggests that work will be occuring soon.</TD> +</TR> + +<TR> +<TD bgcolor="khaki"><font color="black"><b>Works</b></font></TD> +<TD>NetBSD/m68k</TD> +<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:khym@bga.com">Dave Huang <khym@bga.com></a><BR> +</TD> +<TD> +Dave's changes are in the tree. Waiting for verification that it is really finished.</TD> +</TR> + +<TR> +<TD bgcolor="khaki"><font color="black"><b>Partially Working</b></font></TD> +<TD>NetBSD/arm32</TD> +<TD><img alt="Investigating" title="Investigating" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:mpumford@black-star.demon.co.uk">Mike Pumford <mpumford@black-star.demon.co.uk></a> +</TD> +<TD>Mike writes:<BR> +I have started porting to the platform based on the code for Linux ARM. The +InvokeByIndex code works correctly when used with TestXPTCInvoke. I am +currently working on making TestXPC function correctly. +<P> +I am doing the porting work with egcs-1.1.2 on NetBSD 1.4P (NetBSD-current +snapshot from a couple of days ago). +</TD> +</TR> + +<TR> +<TD bgcolor="red"><font color="white"><b>HELP!</b></font></TD> +<TD>linux/ia64</TD> +<TD align="center">-</TD> +<TD>bug <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=40950">40950</a></TD> +</TR> + + +<TR> +<TD bgcolor="red"><font color="white"><b>HELP!</b></font></TD> +<TD>All others!</TD> +<TD align="center">-</TD> +<TD align="center">-</TD> +</TR> + + +</table> + +<p> + +<b>Note:</b> I've used the symbol (<font color="red"><b>?</b></font>) to +indicate people who have expressed an interest in <i>possibly</i> contributing code. +Just because these people are listed here does not mean that they have commited +themselves to do the work. If <b>you</b> would like to contribute then let me +know. Feel free to email these folks and offer to help or find out what's going +on. We're all in this together. + +<p> + +<hr> +<b>Author:</b> <a href="mailto:jband@netscape.com">John Bandhauer <jband@netscape.com></a><br> +<b>Last modified:</b> 3 February 2003 + +</body> +</html> diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/tests/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptcall/tests/.cvsignore new file mode 100644 index 00000000..177fd905 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/tests/.cvsignore @@ -0,0 +1,2 @@ +Makefile +TestXPTCInvoke diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/tests/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptcall/tests/Makefile.in new file mode 100644 index 00000000..a1bf16ca --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/tests/Makefile.in @@ -0,0 +1,64 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = TestXPTC +SIMPLE_PROGRAMS = TestXPTCInvoke$(BIN_SUFFIX) +REQUIRES = xpcom \ + $(NULL) + +CPPSRCS = TestXPTCInvoke.cpp + +LIBS = \ + $(XPCOM_LIBS) \ + $(NSPR_LIBS) \ + $(NULL) + +include $(topsrcdir)/config/rules.mk + +# For _write(). +ifeq ($(OS_ARCH),BSD_OS) +OS_LIBS += -lgcc +endif + + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/tests/TestXPTCInvoke.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptcall/tests/TestXPTCInvoke.cpp new file mode 100644 index 00000000..79e4bc08 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/tests/TestXPTCInvoke.cpp @@ -0,0 +1,1464 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Pierre Phaneuf <pp@ludusdesign.com> + * Stuart Parmenter <pavlov@netscape.com> + * Chris Seawood <cls@seawood.org> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Invoke tests xptcall. */ + +#include <stdio.h> +#include "xptcall.h" +#include "prlong.h" +#include "prinrval.h" +#include "nsMemory.h" + +// forward declration +static int DoMultipleInheritenceTest(int rcExit); +static int DoMultipleInheritenceTest2(int rcExit); +static void DoSpeedTest(); + + +#include <iprt/string.h> + +static char g_szDirect[16384]; +static char g_szInvoke[16384]; +static char *g_pszBuffer = NULL; +static void bufprintf(const char *pszFormat, ...) +{ + va_list va; + va_start(va, pszFormat); + vprintf(pszFormat, va); + va_end(va); + if (g_pszBuffer) + { + size_t cchBuf = strlen(g_pszBuffer); + ssize_t cbLeft = (ssize_t)sizeof(g_szDirect) - (ssize_t)cchBuf; + if (cbLeft > 0) + { + va_list va; + va_start(va, pszFormat); + vsnprintf(&g_pszBuffer[cchBuf], (size_t)cbLeft, pszFormat, va); + va_end(va); + } + } +} + +static void setbuffer(bool fDirect) +{ + g_pszBuffer = fDirect ? g_szDirect : g_szInvoke; + *g_pszBuffer = '\0'; +} + +static int comparebuffers(int rcExit) +{ + if (strcmp(g_szDirect, g_szInvoke) == 0) + return rcExit; + size_t offLine = 0; + unsigned iLine = 1; + for (size_t off = 0; ; off++) + { + char chDirect = g_szDirect[off]; + char chInvoke = g_szInvoke[off]; + if (chDirect == chInvoke) + { + if (!chDirect) + return rcExit; + if (chDirect == '\n') + { + offLine = off + 1; + iLine++; + } + } + else + { + size_t cchDirectLine = RTStrOffCharOrTerm(&g_szDirect[offLine], '\n'); + size_t cchInvokeLine = RTStrOffCharOrTerm(&g_szInvoke[offLine], '\n'); + printf("direct and invoke runs differs on line %u!\n", iLine); + printf("direct: %*.*s\n", (int)cchDirectLine, (int)cchDirectLine, &g_szDirect[offLine]); + printf("invoke: %*.*s\n", (int)cchInvokeLine, (int)cchInvokeLine, &g_szInvoke[offLine]); + + return 1; + } + + } + printf("direct and invoke runs differs!\n"); + return 1; +} + + +// {AAC1FB90-E099-11d2-984E-006008962422} +#define INVOKETESTTARGET_IID \ +{ 0xaac1fb90, 0xe099, 0x11d2, \ + { 0x98, 0x4e, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } } + + +class InvokeTestTargetInterface : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(INVOKETESTTARGET_IID) + NS_IMETHOD AddTwoInts(PRInt32 p1, PRInt32 p2, PRInt32* retval) = 0; + NS_IMETHOD MultTwoInts(PRInt32 p1, PRInt32 p2, PRInt32* retval) = 0; + NS_IMETHOD AddTwoLLs(PRInt64 p1, PRInt64 p2, PRInt64* retval) = 0; + NS_IMETHOD MultTwoLLs(PRInt64 p1, PRInt64 p2, PRInt64* retval) = 0; + + NS_IMETHOD AddManyInts(PRInt32 p1, PRInt32 p2, PRInt32 p3, PRInt32 p4, + PRInt32 p5, PRInt32 p6, PRInt32 p7, PRInt32 p8, + PRInt32 p9, PRInt32 p10, PRInt32* retval) = 0; + + NS_IMETHOD AddTwoFloats(float p1, float p2, float* retval) = 0; + + NS_IMETHOD AddManyDoubles(double p1, double p2, double p3, double p4, + double p5, double p6, double p7, double p8, + double p9, double p10, double* retval) = 0; + + NS_IMETHOD AddManyFloats(float p1, float p2, float p3, float p4, + float p5, float p6, float p7, float p8, + float p9, float p10, float* retval) = 0; + + NS_IMETHOD AddManyManyFloats(float p1, float p2, float p3, float p4, + float p5, float p6, float p7, float p8, + float p9, float p10, float p11, float p12, + float p13, float p14, float p15, float p16, + float p17, float p18, float p19, float p20, + float *retval) = 0; + + NS_IMETHOD AddMixedInts(PRInt64 p1, PRInt32 p2, PRInt64 p3, PRInt32 p4, + PRInt32 p5, PRInt64 p6, PRInt32 p7, PRInt32 p8, + PRInt64 p9, PRInt32 p10, PRInt64* retval) = 0; + + NS_IMETHOD AddMixedInts2(PRInt32 p1, PRInt64 p2, PRInt32 p3, PRInt64 p4, + PRInt64 p5, PRInt32 p6, PRInt64 p7, PRInt64 p8, + PRInt32 p9, PRInt64 p10, PRInt64* retval) = 0; + + NS_IMETHOD AddMixedFloats(float p1, float p2, double p3, double p4, + float p5, float p6, double p7, double p8, + float p9, double p10, float p11, + double *retval) = 0; + + NS_IMETHOD PassTwoStrings(const char* s1, const char* s2, char** retval) = 0; + +}; + +class InvokeTestTarget : public InvokeTestTargetInterface +{ +public: + NS_DECL_ISUPPORTS + NS_IMETHOD AddTwoInts(PRInt32 p1, PRInt32 p2, PRInt32* retval); + NS_IMETHOD MultTwoInts(PRInt32 p1, PRInt32 p2, PRInt32* retval); + NS_IMETHOD AddTwoLLs(PRInt64 p1, PRInt64 p2, PRInt64* retval); + NS_IMETHOD MultTwoLLs(PRInt64 p1, PRInt64 p2, PRInt64* retval); + + NS_IMETHOD AddManyInts(PRInt32 p1, PRInt32 p2, PRInt32 p3, PRInt32 p4, + PRInt32 p5, PRInt32 p6, PRInt32 p7, PRInt32 p8, + PRInt32 p9, PRInt32 p10, PRInt32* retval); + + NS_IMETHOD AddTwoFloats(float p1, float p2, float* retval); + + NS_IMETHOD AddManyDoubles(double p1, double p2, double p3, double p4, + double p5, double p6, double p7, double p8, + double p9, double p10, double* retval); + + NS_IMETHOD AddManyFloats(float p1, float p2, float p3, float p4, + float p5, float p6, float p7, float p8, + float p9, float p10, float* retval); + + NS_IMETHOD AddMixedInts(PRInt64 p1, PRInt32 p2, PRInt64 p3, PRInt32 p4, + PRInt32 p5, PRInt64 p6, PRInt32 p7, PRInt32 p8, + PRInt64 p9, PRInt32 p10, PRInt64* retval); + + NS_IMETHOD AddMixedInts2(PRInt32 p1, PRInt64 p2, PRInt32 p3, PRInt64 p4, + PRInt64 p5, PRInt32 p6, PRInt64 p7, PRInt64 p8, + PRInt32 p9, PRInt64 p10, PRInt64* retval); + + NS_IMETHOD AddMixedFloats(float p1, float p2, double p3, double p4, + float p5, float p6, double p7, double p8, + float p9, double p10, float p11, + double *retval); + + NS_IMETHOD AddManyManyFloats(float p1, float p2, float p3, float p4, + float p5, float p6, float p7, float p8, + float p9, float p10, float p11, float p12, + float p13, float p14, float p15, float p16, + float p17, float p18, float p19, float p20, + float *retval); + + NS_IMETHOD PassTwoStrings(const char* s1, const char* s2, char** retval); + + InvokeTestTarget(); +}; + +NS_IMPL_ISUPPORTS1(InvokeTestTarget, InvokeTestTargetInterface) + +InvokeTestTarget::InvokeTestTarget() +{ + NS_ADDREF_THIS(); +} + +NS_IMETHODIMP +InvokeTestTarget::AddTwoInts(PRInt32 p1, PRInt32 p2, PRInt32* retval) +{ + *retval = p1 + p2; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::MultTwoInts(PRInt32 p1, PRInt32 p2, PRInt32* retval) +{ + *retval = p1 * p2; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::AddTwoLLs(PRInt64 p1, PRInt64 p2, PRInt64* retval) +{ + LL_ADD(*retval, p1, p2); + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::MultTwoLLs(PRInt64 p1, PRInt64 p2, PRInt64* retval) +{ + LL_MUL(*retval, p1, p2); + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::AddManyInts(PRInt32 p1, PRInt32 p2, PRInt32 p3, PRInt32 p4, + PRInt32 p5, PRInt32 p6, PRInt32 p7, PRInt32 p8, + PRInt32 p9, PRInt32 p10, PRInt32* retval) +{ +#ifdef DEBUG_TESTINVOKE + printf("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", + p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); +#endif + *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::AddTwoFloats(float p1, float p2, float *retval) +{ +#ifdef DEBUG_TESTINVOKE + printf("%f, %f\n", p1, p2); +#endif + *retval = p1 + p2; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::AddManyDoubles(double p1, double p2, double p3, double p4, + double p5, double p6, double p7, double p8, + double p9, double p10, double* retval) +{ +#ifdef DEBUG_TESTINVOKE + printf("%lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf\n", + p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); +#endif + *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::AddManyFloats(float p1, float p2, float p3, float p4, + float p5, float p6, float p7, float p8, + float p9, float p10, float* retval) +{ +#ifdef DEBUG_TESTINVOKE + printf("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n", + p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); +#endif + *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::AddMixedFloats(float p1, float p2, double p3, double p4, + float p5, float p6, double p7, double p8, + float p9, double p10, float p11, + double *retval) +{ +#ifdef DEBUG_TESTINVOKE + printf("%f, %f, %lf, %lf, %f, %f, %lf, %lf, %f, %lf, %f\n", + p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); +#endif + *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 + p11; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::AddManyManyFloats(float p1, float p2, float p3, float p4, + float p5, float p6, float p7, float p8, + float p9, float p10, float p11, float p12, + float p13, float p14, float p15, float p16, + float p17, float p18, float p19, float p20, + float *retval) +{ +#ifdef DEBUG_TESTINVOKE + printf("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, " + "%f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n", + p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11, p12, p13, p14, p15, p16, p17, p18, p19, p20); +#endif + *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 + + p11 + p12 + p13 + p14 + p15 + p16 + p17 + p18 + p19 + p20; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::AddMixedInts(PRInt64 p1, PRInt32 p2, PRInt64 p3, PRInt32 p4, + PRInt32 p5, PRInt64 p6, PRInt32 p7, PRInt32 p8, + PRInt64 p9, PRInt32 p10, PRInt64* retval) +{ + *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::AddMixedInts2(PRInt32 p1, PRInt64 p2, PRInt32 p3, PRInt64 p4, + PRInt64 p5, PRInt32 p6, PRInt64 p7, PRInt64 p8, + PRInt32 p9, PRInt64 p10, PRInt64* retval) +{ + *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10; + return NS_OK; +} + +NS_IMETHODIMP +InvokeTestTarget::PassTwoStrings(const char* s1, const char* s2, char** retval) +{ + const char milk[] = "milk"; + char *ret = (char*)nsMemory::Alloc(sizeof(milk)); + if (!ret) + return NS_ERROR_OUT_OF_MEMORY; + strncpy(ret, milk, sizeof(milk)); + printf("\t%s %s", s1, s2); + *retval = ret; + return NS_OK; +} + +int main() +{ + InvokeTestTarget *test = new InvokeTestTarget(); + + /* here we make the global 'check for alloc failure' checker happy */ + if(!test) + return 1; + + PRInt32 out, tmp32 = 0; + PRInt64 out64; + printf("calling direct:\n"); + setbuffer(true); + if(NS_SUCCEEDED(test->AddTwoInts(1,1,&out))) + bufprintf("\t1 + 1 = %d\n", out); + else + bufprintf("\tFAILED"); + PRInt64 one, two; + LL_I2L(one, 1); + LL_I2L(two, 2); + if(NS_SUCCEEDED(test->AddTwoLLs(one,one,&out64))) + { + LL_L2I(tmp32, out64); + bufprintf("\t1L + 1L = %d\n", (int)tmp32); + } + else + bufprintf("\tFAILED"); + if(NS_SUCCEEDED(test->MultTwoInts(2,2,&out))) + bufprintf("\t2 * 2 = %d\n", out); + else + bufprintf("\tFAILED"); + if(NS_SUCCEEDED(test->MultTwoLLs(two,two,&out64))) + { + LL_L2I(tmp32, out64); + bufprintf("\t2L * 2L = %d\n", (int)tmp32); + } + else + bufprintf("\tFAILED"); + + double outD; + float outF; + PRInt32 outI; + char *outS; + + if(NS_SUCCEEDED(test->AddManyInts(1,2,3,4,5,6,7,8,9,10,&outI))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", outI); + else + bufprintf("\tFAILED"); + + if(NS_SUCCEEDED(test->AddTwoFloats(1,2,&outF))) + bufprintf("\t1 + 2 = %ff\n", (double)outF); + else + bufprintf("\tFAILED"); + + if(NS_SUCCEEDED(test->AddManyDoubles(1,2,3,4,5,6,7,8,9,10,&outD))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %f\n", outD); + else + bufprintf("\tFAILED"); + + if(NS_SUCCEEDED(test->AddManyFloats(1,2,3,4,5,6,7,8,9,10,&outF))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %ff\n", (double)outF); + else + bufprintf("\tFAILED"); + + if(NS_SUCCEEDED(test->AddManyManyFloats(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,&outF))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 = %ff\n", (double)outF); + else + bufprintf("\tFAILED"); + + if(NS_SUCCEEDED(test->AddMixedInts(1,2,3,4,5,6,7,8,9,10,&out64))) + { + LL_L2I(tmp32, out64); + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", (int)tmp32); + } + else + bufprintf("\tFAILED"); + + if(NS_SUCCEEDED(test->AddMixedInts2(1,2,3,4,5,6,7,8,9,10,&out64))) + { + LL_L2I(tmp32, out64); + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", (int)tmp32); + } + else + bufprintf("\tFAILED"); + + if(NS_SUCCEEDED(test->AddMixedFloats(1,2,3,4,5,6,7,8,9,10,11,&outD))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 = %f\n", (double)outD); + else + bufprintf("\tFAILED"); + + if (NS_SUCCEEDED(test->PassTwoStrings("moo","cow",&outS))) { + bufprintf(" = %s\n", outS); + nsMemory::Free(outS); + } else + bufprintf("\tFAILED"); + + printf("calling via invoke:\n"); + setbuffer(false); + + nsXPTCVariant var[21]; + + var[0].val.i32 = 1; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + + var[1].val.i32 = 1; + var[1].type = nsXPTType::T_I32; + var[1].flags = 0; + + var[2].val.i32 = 0; + var[2].type = nsXPTType::T_I32; + var[2].flags = nsXPTCVariant::PTR_IS_DATA; + var[2].ptr = &var[2].val.i32; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 3, 3, var))) + bufprintf("\t1 + 1 = %d\n", var[2].val.i32); + else + bufprintf("\tFAILED"); + + LL_I2L(var[0].val.i64, 1); + var[0].type = nsXPTType::T_I64; + var[0].flags = 0; + + LL_I2L(var[1].val.i64, 1); + var[1].type = nsXPTType::T_I64; + var[1].flags = 0; + + LL_I2L(var[2].val.i64, 0); + var[2].type = nsXPTType::T_I64; + var[2].flags = nsXPTCVariant::PTR_IS_DATA; + var[2].ptr = &var[2].val.i64; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 5, 3, var))) + bufprintf("\t1L + 1L = %d\n", (int)var[2].val.i64); + else + bufprintf("\tFAILED"); + + var[0].val.i32 = 2; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + + var[1].val.i32 = 2; + var[1].type = nsXPTType::T_I32; + var[1].flags = 0; + + var[2].val.i32 = 0; + var[2].type = nsXPTType::T_I32; + var[2].flags = nsXPTCVariant::PTR_IS_DATA; + var[2].ptr = &var[2].val.i32; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 4, 3, var))) + bufprintf("\t2 * 2 = %d\n", var[2].val.i32); + else + bufprintf("\tFAILED"); + + LL_I2L(var[0].val.i64,2); + var[0].type = nsXPTType::T_I64; + var[0].flags = 0; + + LL_I2L(var[1].val.i64,2); + var[1].type = nsXPTType::T_I64; + var[1].flags = 0; + + LL_I2L(var[2].val.i64,0); + var[2].type = nsXPTType::T_I64; + var[2].flags = nsXPTCVariant::PTR_IS_DATA; + var[2].ptr = &var[2].val.i64; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 6, 3, var))) + bufprintf("\t2L * 2L = %d\n", (int)var[2].val.i64); + else + bufprintf("\tFAILED"); + + var[0].val.i32 = 1; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + + var[1].val.i32 = 2; + var[1].type = nsXPTType::T_I32; + var[1].flags = 0; + + var[2].val.i32 = 3; + var[2].type = nsXPTType::T_I32; + var[2].flags = 0; + + var[3].val.i32 = 4; + var[3].type = nsXPTType::T_I32; + var[3].flags = 0; + + var[4].val.i32 = 5; + var[4].type = nsXPTType::T_I32; + var[4].flags = 0; + + var[5].val.i32 = 6; + var[5].type = nsXPTType::T_I32; + var[5].flags = 0; + + var[6].val.i32 = 7; + var[6].type = nsXPTType::T_I32; + var[6].flags = 0; + + var[7].val.i32 = 8; + var[7].type = nsXPTType::T_I32; + var[7].flags = 0; + + var[8].val.i32 = 9; + var[8].type = nsXPTType::T_I32; + var[8].flags = 0; + + var[9].val.i32 = 10; + var[9].type = nsXPTType::T_I32; + var[9].flags = 0; + + var[10].val.i32 = 0; + var[10].type = nsXPTType::T_I32; + var[10].flags = nsXPTCVariant::PTR_IS_DATA; + var[10].ptr = &var[10].val.i32; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 7, 11, var))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", + var[10].val.i32); + + var[0].val.f = 1.0f; + var[0].type = nsXPTType::T_FLOAT; + var[0].flags = 0; + + var[1].val.f = 2.0f; + var[1].type = nsXPTType::T_FLOAT; + var[1].flags = 0; + + var[2].val.f = 0.0f; + var[2].type = nsXPTType::T_FLOAT; + var[2].flags = nsXPTCVariant::PTR_IS_DATA; + var[2].ptr = &var[2].val.f; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 8, 3, var))) + bufprintf("\t1 + 2 = %ff\n", + (double) var[2].val.f); + + + var[0].val.d = 1.0; + var[0].type = nsXPTType::T_DOUBLE; + var[0].flags = 0; + + var[1].val.d = 2.0; + var[1].type = nsXPTType::T_DOUBLE; + var[1].flags = 0; + + var[2].val.d = 3.0; + var[2].type = nsXPTType::T_DOUBLE; + var[2].flags = 0; + + var[3].val.d = 4.0; + var[3].type = nsXPTType::T_DOUBLE; + var[3].flags = 0; + + var[4].val.d = 5.0; + var[4].type = nsXPTType::T_DOUBLE; + var[4].flags = 0; + + var[5].val.d = 6.0; + var[5].type = nsXPTType::T_DOUBLE; + var[5].flags = 0; + + var[6].val.d = 7.0; + var[6].type = nsXPTType::T_DOUBLE; + var[6].flags = 0; + + var[7].val.d = 8.0; + var[7].type = nsXPTType::T_DOUBLE; + var[7].flags = 0; + + var[8].val.d = 9.0; + var[8].type = nsXPTType::T_DOUBLE; + var[8].flags = 0; + + var[9].val.d = 10.0; + var[9].type = nsXPTType::T_DOUBLE; + var[9].flags = 0; + + var[10].val.d = 0.0; + var[10].type = nsXPTType::T_DOUBLE; + var[10].flags = nsXPTCVariant::PTR_IS_DATA; + var[10].ptr = &var[10].val.d; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 9, 11, var))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %f\n", + var[10].val.d); + else + bufprintf("\tFAILED"); + + var[0].val.f = 1.0f; + var[0].type = nsXPTType::T_FLOAT; + var[0].flags = 0; + + var[1].val.f = 2.0f; + var[1].type = nsXPTType::T_FLOAT; + var[1].flags = 0; + + var[2].val.f = 3.0f; + var[2].type = nsXPTType::T_FLOAT; + var[2].flags = 0; + + var[3].val.f = 4.0f; + var[3].type = nsXPTType::T_FLOAT; + var[3].flags = 0; + + var[4].val.f = 5.0f; + var[4].type = nsXPTType::T_FLOAT; + var[4].flags = 0; + + var[5].val.f = 6.0f; + var[5].type = nsXPTType::T_FLOAT; + var[5].flags = 0; + + var[6].val.f = 7.0f; + var[6].type = nsXPTType::T_FLOAT; + var[6].flags = 0; + + var[7].val.f = 8.0f; + var[7].type = nsXPTType::T_FLOAT; + var[7].flags = 0; + + var[8].val.f = 9.0f; + var[8].type = nsXPTType::T_FLOAT; + var[8].flags = 0; + + var[9].val.f = 10.0f; + var[9].type = nsXPTType::T_FLOAT; + var[9].flags = 0; + + var[10].val.f = 0.0f; + var[10].type = nsXPTType::T_FLOAT; + var[10].flags = nsXPTCVariant::PTR_IS_DATA; + var[10].ptr = &var[10].val.f; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 10, 11, var))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %ff\n", + (double) var[10].val.f); + else + bufprintf("\tFAILED"); + + var[0].val.f = 1.0f; + var[0].type = nsXPTType::T_FLOAT; + var[0].flags = 0; + + var[1].val.f = 2.0f; + var[1].type = nsXPTType::T_FLOAT; + var[1].flags = 0; + + var[2].val.f = 3.0f; + var[2].type = nsXPTType::T_FLOAT; + var[2].flags = 0; + + var[3].val.f = 4.0f; + var[3].type = nsXPTType::T_FLOAT; + var[3].flags = 0; + + var[4].val.f = 5.0f; + var[4].type = nsXPTType::T_FLOAT; + var[4].flags = 0; + + var[5].val.f = 6.0f; + var[5].type = nsXPTType::T_FLOAT; + var[5].flags = 0; + + var[6].val.f = 7.0f; + var[6].type = nsXPTType::T_FLOAT; + var[6].flags = 0; + + var[7].val.f = 8.0f; + var[7].type = nsXPTType::T_FLOAT; + var[7].flags = 0; + + var[8].val.f = 9.0f; + var[8].type = nsXPTType::T_FLOAT; + var[8].flags = 0; + + var[9].val.f = 10.0f; + var[9].type = nsXPTType::T_FLOAT; + var[9].flags = 0; + + var[10].val.f = 11.0f; + var[10].type = nsXPTType::T_FLOAT; + var[10].flags = 0; + + var[11].val.f = 12.0f; + var[11].type = nsXPTType::T_FLOAT; + var[11].flags = 0; + + var[12].val.f = 13.0f; + var[12].type = nsXPTType::T_FLOAT; + var[12].flags = 0; + + var[13].val.f = 14.0f; + var[13].type = nsXPTType::T_FLOAT; + var[13].flags = 0; + + var[14].val.f = 15.0f; + var[14].type = nsXPTType::T_FLOAT; + var[14].flags = 0; + + var[15].val.f = 16.0f; + var[15].type = nsXPTType::T_FLOAT; + var[15].flags = 0; + + var[16].val.f = 17.0f; + var[16].type = nsXPTType::T_FLOAT; + var[16].flags = 0; + + var[17].val.f = 18.0f; + var[17].type = nsXPTType::T_FLOAT; + var[17].flags = 0; + + var[18].val.f = 19.0f; + var[18].type = nsXPTType::T_FLOAT; + var[18].flags = 0; + + var[19].val.f = 20.0f; + var[19].type = nsXPTType::T_FLOAT; + var[19].flags = 0; + + var[20].val.f = 0.0f; + var[20].type = nsXPTType::T_FLOAT; + var[20].flags = nsXPTCVariant::PTR_IS_DATA; + var[20].ptr = &var[20].val.f; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 11, 21, var))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 = %ff\n", + (double) var[20].val.f); + + var[0].val.i64 = 1; + var[0].type = nsXPTType::T_I64; + var[0].flags = 0; + + var[1].val.i32 = 2; + var[1].type = nsXPTType::T_I32; + var[1].flags = 0; + + var[2].val.i64 = 3; + var[2].type = nsXPTType::T_I64; + var[2].flags = 0; + + var[3].val.i32 = 4; + var[3].type = nsXPTType::T_I32; + var[3].flags = 0; + + var[4].val.i32 = 5; + var[4].type = nsXPTType::T_I32; + var[4].flags = 0; + + var[5].val.i64 = 6; + var[5].type = nsXPTType::T_I64; + var[5].flags = 0; + + var[6].val.i32 = 7; + var[6].type = nsXPTType::T_I32; + var[6].flags = 0; + + var[7].val.i32 = 8; + var[7].type = nsXPTType::T_I32; + var[7].flags = 0; + + var[8].val.i64 = 9; + var[8].type = nsXPTType::T_I64; + var[8].flags = 0; + + var[9].val.i32 = 10; + var[9].type = nsXPTType::T_I32; + var[9].flags = 0; + + var[10].val.i64 = 0; + var[10].type = nsXPTType::T_I64; + var[10].flags = nsXPTCVariant::PTR_IS_DATA; + var[10].ptr = &var[10].val.i64; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 12, 11, var))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", + (int)var[10].val.i64); + else + bufprintf("\tFAILED"); + + var[0].val.i32 = 1; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + + var[1].val.i64 = 2; + var[1].type = nsXPTType::T_I64; + var[1].flags = 0; + + var[2].val.i32 = 3; + var[2].type = nsXPTType::T_I32; + var[2].flags = 0; + + var[3].val.i64 = 4; + var[3].type = nsXPTType::T_I64; + var[3].flags = 0; + + var[4].val.i64 = 5; + var[4].type = nsXPTType::T_I64; + var[4].flags = 0; + + var[5].val.i32 = 6; + var[5].type = nsXPTType::T_I32; + var[5].flags = 0; + + var[6].val.i64 = 7; + var[6].type = nsXPTType::T_I64; + var[6].flags = 0; + + var[7].val.i64 = 8; + var[7].type = nsXPTType::T_I64; + var[7].flags = 0; + + var[8].val.i32 = 9; + var[8].type = nsXPTType::T_I32; + var[8].flags = 0; + + var[9].val.i64 = 10; + var[9].type = nsXPTType::T_I64; + var[9].flags = 0; + + var[10].val.i64 = 0; + var[10].type = nsXPTType::T_I64; + var[10].flags = nsXPTCVariant::PTR_IS_DATA; + var[10].ptr = &var[10].val.i64; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 13, 11, var))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", + (int)var[10].val.i64); + else + bufprintf("\tFAILED"); + + var[0].val.f = 1.0f; + var[0].type = nsXPTType::T_FLOAT; + var[0].flags = 0; + + var[1].val.f = 2.0f; + var[1].type = nsXPTType::T_FLOAT; + var[1].flags = 0; + + var[2].val.d = 3.0; + var[2].type = nsXPTType::T_DOUBLE; + var[2].flags = 0; + + var[3].val.d = 4.0; + var[3].type = nsXPTType::T_DOUBLE; + var[3].flags = 0; + + var[4].val.f = 5.0f; + var[4].type = nsXPTType::T_FLOAT; + var[4].flags = 0; + + var[5].val.f = 6.0f; + var[5].type = nsXPTType::T_FLOAT; + var[5].flags = 0; + + var[6].val.d = 7.0; + var[6].type = nsXPTType::T_DOUBLE; + var[6].flags = 0; + + var[7].val.d = 8.0; + var[7].type = nsXPTType::T_DOUBLE; + var[7].flags = 0; + + var[8].val.f = 9.0f; + var[8].type = nsXPTType::T_FLOAT; + var[8].flags = 0; + + var[9].val.d = 10.0; + var[9].type = nsXPTType::T_DOUBLE; + var[9].flags = 0; + + var[10].val.f = 11.0f; + var[10].type = nsXPTType::T_FLOAT; + var[10].flags = 0; + + var[11].val.d = 0.0; + var[11].type = nsXPTType::T_DOUBLE; + var[11].flags = nsXPTCVariant::PTR_IS_DATA; + var[11].ptr = &var[11].val.d; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 14, 12, var))) + bufprintf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 = %f\n", + var[11].val.d); + else + bufprintf("\tFAILED"); + + var[0].val.p = (void*)"moo"; + var[0].type = nsXPTType::T_CHAR_STR; + var[0].flags = 0; + + var[1].val.p = (void*)"cow"; + var[1].type = nsXPTType::T_CHAR_STR; + var[1].flags = 0; + + var[2].val.p = 0; + var[2].type = nsXPTType::T_CHAR_STR; + var[2].flags = nsXPTCVariant::PTR_IS_DATA; + var[2].ptr = &var[2].val.p; + + if(NS_SUCCEEDED(XPTC_InvokeByIndex(test, 15, 3, var))) + { + bufprintf(" = %s\n", var[2].val.p); + nsMemory::Free(var[2].val.p); + } + else + bufprintf("\tFAILED"); + int rcExit = comparebuffers(0); + + rcExit = DoMultipleInheritenceTest(rcExit); + rcExit = DoMultipleInheritenceTest2(rcExit); + // Disabled by default - takes too much time on slow machines + //DoSpeedTest(); + + NS_RELEASE(test); + + return rcExit; +} + +/***************************************************************************/ +/***************************************************************************/ +/***************************************************************************/ + +// {491C65A0-3317-11d3-9885-006008962422} +#define FOO_IID \ +{ 0x491c65a0, 0x3317, 0x11d3, \ + { 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } } + +// {491C65A1-3317-11d3-9885-006008962422} +#define BAR_IID \ +{ 0x491c65a1, 0x3317, 0x11d3, \ + { 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } } + +/***************************/ + +class nsIFoo : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(FOO_IID) + NS_IMETHOD FooMethod1(PRInt32 i) = 0; + NS_IMETHOD FooMethod2(PRInt32 i) = 0; +}; + +class nsIBar : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(BAR_IID) + NS_IMETHOD BarMethod1(PRInt32 i) = 0; + NS_IMETHOD BarMethod2(PRInt32 i) = 0; +}; + +/***************************/ + +class FooImpl : public nsIFoo +{ +public: + NS_IMETHOD FooMethod1(PRInt32 i); + NS_IMETHOD FooMethod2(PRInt32 i); + + FooImpl(); + +protected: + ~FooImpl() {} + +public: + virtual const char* ImplName() = 0; + + int SomeData1; + int SomeData2; + const char* Name; +}; + +class BarImpl : public nsIBar +{ +public: + NS_IMETHOD BarMethod1(PRInt32 i); + NS_IMETHOD BarMethod2(PRInt32 i); + + BarImpl(); + +protected: + ~BarImpl() {} + +public: + virtual const char * ImplName() = 0; + + int SomeData1; + int SomeData2; + const char* Name; +}; + +/***************************/ + +FooImpl::FooImpl() : Name("FooImpl") +{ +} + +NS_IMETHODIMP FooImpl::FooMethod1(PRInt32 i) +{ + bufprintf("\tFooImpl::FooMethod1 called with i == %d, %s part of a %s\n", + i, Name, ImplName()); + return NS_OK; +} + +NS_IMETHODIMP FooImpl::FooMethod2(PRInt32 i) +{ + bufprintf("\tFooImpl::FooMethod2 called with i == %d, %s part of a %s\n", + i, Name, ImplName()); + return NS_OK; +} + +/***************************/ + +BarImpl::BarImpl() : Name("BarImpl") +{ +} + +NS_IMETHODIMP BarImpl::BarMethod1(PRInt32 i) +{ + bufprintf("\tBarImpl::BarMethod1 called with i == %d, %s part of a %s\n", + i, Name, ImplName()); + return NS_OK; +} + +NS_IMETHODIMP BarImpl::BarMethod2(PRInt32 i) +{ + bufprintf("\tBarImpl::BarMethod2 called with i == %d, %s part of a %s\n", + i, Name, ImplName()); + return NS_OK; +} + +/***************************/ + +class FooBarImpl : public FooImpl, public BarImpl +{ +public: + NS_DECL_ISUPPORTS + + const char* ImplName(); + + FooBarImpl(); + +private: + ~FooBarImpl() {} + +public: + const char* MyName; +}; + +FooBarImpl::FooBarImpl() : MyName("FooBarImpl") +{ + NS_ADDREF_THIS(); +} + +const char* FooBarImpl::ImplName() +{ + return MyName; +} + +NS_IMETHODIMP +FooBarImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + + *aInstancePtr = NULL; + + + if (aIID.Equals(NS_GET_IID(nsIFoo))) { + *aInstancePtr = (void*) NS_STATIC_CAST(nsIFoo*,this); + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsIBar))) { + *aInstancePtr = (void*) NS_STATIC_CAST(nsIBar*,this); + NS_ADDREF_THIS(); + return NS_OK; + } + + if (aIID.Equals(NS_GET_IID(nsISupports))) { + *aInstancePtr = (void*) NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(nsIFoo*,this)); + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +NS_IMPL_ADDREF(FooBarImpl) +NS_IMPL_RELEASE(FooBarImpl) + + +static int DoMultipleInheritenceTest(int rcExit) +{ + FooBarImpl* impl = new FooBarImpl(); + if(!impl) + return 1; + + nsIFoo* foo; + nsIBar* bar; + + nsXPTCVariant var[1]; + + printf("\n"); + if(NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIFoo), (void**)&foo)) && + NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIBar), (void**)&bar))) + { + printf("impl == %p\n", impl); + printf("foo == %p\n", foo); + printf("bar == %p\n", bar); + + printf("Calling Foo...\n"); + printf("direct calls:\n"); + setbuffer(true); + foo->FooMethod1(1); + foo->FooMethod2(2); + + printf("invoke calls:\n"); + setbuffer(false); + var[0].val.i32 = 1; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + XPTC_InvokeByIndex(foo, 3, 1, var); + + var[0].val.i32 = 2; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + XPTC_InvokeByIndex(foo, 4, 1, var); + + rcExit = comparebuffers(rcExit); + printf("\n"); + + printf("Calling Bar...\n"); + printf("direct calls:\n"); + setbuffer(true); + bar->BarMethod1(1); + bar->BarMethod2(2); + + printf("invoke calls:\n"); + setbuffer(false); + var[0].val.i32 = 1; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + XPTC_InvokeByIndex(bar, 3, 1, var); + + var[0].val.i32 = 2; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + XPTC_InvokeByIndex(bar, 4, 1, var); + + rcExit = comparebuffers(rcExit); + printf("\n"); + + NS_RELEASE(foo); + NS_RELEASE(bar); + } + else + rcExit = 1; + NS_RELEASE(impl); + return rcExit; +} +/***************************************************************************/ +/***************************************************************************/ +/***************************************************************************/ +/* This is a variation on the theme submitted by duncan@be.com (Duncan Wilcox). +* He was seeing the other test work and this test not work. They should both +* Work on any given platform +*/ + +class nsIFoo2 : public nsISupports +{ +public: + NS_IMETHOD FooMethod1(PRInt32 i) = 0; + NS_IMETHOD FooMethod2(PRInt32 i) = 0; +}; + +class nsIBar2 : public nsISupports +{ +public: + NS_IMETHOD BarMethod1(PRInt32 i) = 0; + NS_IMETHOD BarMethod2(PRInt32 i) = 0; +}; + +class FooBarImpl2 : public nsIFoo2, public nsIBar2 +{ +public: + // Foo interface + NS_IMETHOD FooMethod1(PRInt32 i); + NS_IMETHOD FooMethod2(PRInt32 i); + + // Bar interface + NS_IMETHOD BarMethod1(PRInt32 i); + NS_IMETHOD BarMethod2(PRInt32 i); + + NS_DECL_ISUPPORTS + + FooBarImpl2(); + +private: + ~FooBarImpl2() {} + +public: + PRInt32 value; +}; + +FooBarImpl2::FooBarImpl2() : value(0x12345678) +{ + NS_ADDREF_THIS(); +} + +NS_IMETHODIMP FooBarImpl2::FooMethod1(PRInt32 i) +{ + bufprintf("\tFooBarImpl2::FooMethod1 called with i == %d, local value = %x\n", + i, value); + return NS_OK; +} + +NS_IMETHODIMP FooBarImpl2::FooMethod2(PRInt32 i) +{ + bufprintf("\tFooBarImpl2::FooMethod2 called with i == %d, local value = %x\n", + i, value); + return NS_OK; +} + +NS_IMETHODIMP FooBarImpl2::BarMethod1(PRInt32 i) +{ + bufprintf("\tFooBarImpl2::BarMethod1 called with i == %d, local value = %x\n", + i, value); + return NS_OK; +} + +NS_IMETHODIMP FooBarImpl2::BarMethod2(PRInt32 i) +{ + bufprintf("\tFooBarImpl2::BarMethod2 called with i == %d, local value = %x\n", + i, value); + return NS_OK; +} + +NS_IMETHODIMP +FooBarImpl2::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + + *aInstancePtr = NULL; + + + if (aIID.Equals(NS_GET_IID(nsIFoo))) { + *aInstancePtr = (void*) NS_STATIC_CAST(nsIFoo2*,this); + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsIBar))) { + *aInstancePtr = (void*) NS_STATIC_CAST(nsIBar2*,this); + NS_ADDREF_THIS(); + return NS_OK; + } + + if (aIID.Equals(NS_GET_IID(nsISupports))) { + *aInstancePtr = (void*) NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(nsIFoo2*,this)); + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +NS_IMPL_ADDREF(FooBarImpl2) +NS_IMPL_RELEASE(FooBarImpl2) + +static int DoMultipleInheritenceTest2(int rcExit) +{ + FooBarImpl2* impl = new FooBarImpl2(); + if(!impl) + return 1; + + nsIFoo2* foo; + nsIBar2* bar; + + nsXPTCVariant var[1]; + + printf("\n"); + if(NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIFoo), (void**)&foo)) && + NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIBar), (void**)&bar))) + { + printf("impl == %p\n", impl); + printf("foo == %p\n", foo); + printf("bar == %p\n", bar); + + printf("Calling Foo...\n"); + printf("direct calls:\n"); + setbuffer(true); + foo->FooMethod1(1); + foo->FooMethod2(2); + + printf("invoke calls:\n"); + setbuffer(false); + var[0].val.i32 = 1; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + XPTC_InvokeByIndex(foo, 3, 1, var); + + var[0].val.i32 = 2; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + XPTC_InvokeByIndex(foo, 4, 1, var); + + rcExit = comparebuffers(rcExit); + printf("\n"); + + printf("Calling Bar...\n"); + printf("direct calls:\n"); + setbuffer(true); + bar->BarMethod1(1); + bar->BarMethod2(2); + + printf("invoke calls:\n"); + setbuffer(false); + var[0].val.i32 = 1; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + XPTC_InvokeByIndex(bar, 3, 1, var); + + var[0].val.i32 = 2; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + XPTC_InvokeByIndex(bar, 4, 1, var); + + rcExit = comparebuffers(rcExit); + printf("\n"); + + NS_RELEASE(foo); + NS_RELEASE(bar); + } + else + rcExit = 1; + NS_RELEASE(impl); + return rcExit; +} + +static void DoSpeedTest() +{ + InvokeTestTarget *test = new InvokeTestTarget(); + + nsXPTCVariant var[3]; + + var[0].val.i32 = 1; + var[0].type = nsXPTType::T_I32; + var[0].flags = 0; + + var[1].val.i32 = 1; + var[1].type = nsXPTType::T_I32; + var[1].flags = 0; + + var[2].val.i32 = 0; + var[2].type = nsXPTType::T_I32; + var[2].flags = nsXPTCVariant::PTR_IS_DATA; + var[2].ptr = &var[2].val.i32; + + PRInt32 in1 = 1; + PRInt32 in2 = 1; + PRInt32 out; + + // Crank this number down if your platform is slow :) + static const int count = 100000000; + int i; + PRIntervalTime start; + PRIntervalTime interval_direct; + PRIntervalTime interval_invoke; + + printf("Speed test...\n\n"); + printf("Doing %d direct call iterations...\n", count); + start = PR_IntervalNow(); + for(i = count; i; i--) + (void)test->AddTwoInts(in1, in2, &out); + interval_direct = PR_IntervalNow() - start; + + printf("Doing %d invoked call iterations...\n", count); + start = PR_IntervalNow(); + for(i = count; i; i--) + (void)XPTC_InvokeByIndex(test, 3, 3, var); + interval_invoke = PR_IntervalNow() - start; + + printf(" direct took %0.2f seconds\n", + (double)interval_direct/(double)PR_TicksPerSecond()); + printf(" invoke took %0.2f seconds\n", + (double)interval_invoke/(double)PR_TicksPerSecond()); + printf(" So, invoke overhead was ~ %0.2f seconds (~ %0.0f%%)\n", + (double)(interval_invoke-interval_direct)/(double)PR_TicksPerSecond(), + (double)(interval_invoke-interval_direct)/(double)interval_invoke*100); +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/Makefile.in new file mode 100644 index 00000000..d7e3b9c8 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/Makefile.in @@ -0,0 +1,49 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1999 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +DIRS = public src + +include $(topsrcdir)/config/rules.mk + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/Makefile.in new file mode 100644 index 00000000..dbf13d8b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/Makefile.in @@ -0,0 +1,66 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1999 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom + +XPIDL_MODULE = xpcom_xpti + +GRE_MODULE = 1 + +EXPORTS = \ + xptinfo.h \ + $(NULL) + +XPIDLSRCS = \ + nsIInterfaceInfo.idl \ + nsIInterfaceInfoManager.idl \ + nsIXPTLoader.idl \ + $(NULL) + +EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) + +include $(topsrcdir)/config/rules.mk + +CFLAGS += -DEXPORT_XPCI_API + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/nsIInterfaceInfo.idl b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/nsIInterfaceInfo.idl new file mode 100644 index 00000000..f77dbcfc --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/nsIInterfaceInfo.idl @@ -0,0 +1,137 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsIInterfaceInfo public declaration. */ + + +#include "nsISupports.idl" + +// forward declaration of non-XPCOM types + +[ptr] native nsXPTMethodInfoPtr(nsXPTMethodInfo); +[ptr] native nsXPTConstantPtr(nsXPTConstant); +[ptr] native nsXPTParamInfoPtr(nsXPTParamInfo); + native nsXPTType(nsXPTType); + +// We bend the rules to do a [shared] nsIID (but this is never scriptable) +[ptr] native nsIIDPtrShared(nsIID); + +%{C++ +class nsXPTMethodInfo; +class nsXPTConstant; +class nsXPTParamInfo; +class nsXPTType; +%} + +/* this is NOT intended to be scriptable */ +[uuid(215DBE04-94A7-11d2-BA58-00805F8A5DD7)] +interface nsIInterfaceInfo : nsISupports +{ + readonly attribute string name; + readonly attribute nsIIDPtr InterfaceIID; + + PRBool isScriptable(); + + readonly attribute nsIInterfaceInfo parent; + + /** + * These include counts for parent (and all ancestors). + */ + readonly attribute PRUint16 methodCount; + readonly attribute PRUint16 constantCount; + + /** + * These include methods and constants for parent (and all ancestors). + * + * These do *not* make copies ***explicit bending of XPCOM rules***. + */ + + void getMethodInfo(in PRUint16 index, + [shared, retval] out nsXPTMethodInfoPtr info); + + void getMethodInfoForName(in string methodName, out PRUint16 index, + [shared, retval] out nsXPTMethodInfoPtr info); + + void getConstant(in PRUint16 index, + [shared, retval] out nsXPTConstantPtr constant); + + + /** + * Get the interface information or iid associated with a param of some + * method in this interface. + */ + + nsIInterfaceInfo getInfoForParam(in PRUint16 methodIndex, + [const] in nsXPTParamInfoPtr param); + + nsIIDPtr getIIDForParam(in PRUint16 methodIndex, + [const] in nsXPTParamInfoPtr param); + + + /** + * These do *not* make copies ***explicit bending of XPCOM rules***. + */ + + nsXPTType getTypeForParam(in PRUint16 methodIndex, + [const] in nsXPTParamInfoPtr param, + in PRUint16 dimension); + + PRUint8 getSizeIsArgNumberForParam(in PRUint16 methodIndex, + [const] in nsXPTParamInfoPtr param, + in PRUint16 dimension); + + PRUint8 getLengthIsArgNumberForParam(in PRUint16 methodIndex, + [const] in nsXPTParamInfoPtr param, + in PRUint16 dimension); + + PRUint8 getInterfaceIsArgNumberForParam(in PRUint16 methodIndex, + [const] in nsXPTParamInfoPtr param); + + PRBool isIID(in nsIIDPtr IID); + + void getNameShared([shared,retval] out string name); + void getIIDShared([shared,retval] out nsIIDPtrShared iid); + + PRBool isFunction(); + + PRBool hasAncestor(in nsIIDPtr iid); + + [notxpcom] nsresult getIIDForParamNoAlloc(in PRUint16 methodIndex, + [const] in nsXPTParamInfoPtr param, + out nsIID iid); +}; + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/nsIInterfaceInfoManager.idl b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/nsIInterfaceInfoManager.idl new file mode 100644 index 00000000..48277691 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/nsIInterfaceInfoManager.idl @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsIInterfaceInfoManager public declaration. */ + + +#include "nsISupports.idl" +#include "nsIInterfaceInfo.idl" +#include "nsIEnumerator.idl" +#include "nsISimpleEnumerator.idl" + +/* this is NOT intended to be scriptable */ +[uuid(8B161900-BE2B-11d2-9831-006008962422)] +interface nsIInterfaceInfoManager : nsISupports +{ + nsIInterfaceInfo getInfoForIID(in nsIIDPtr iid); + nsIInterfaceInfo getInfoForName(in string name); + + nsIIDPtr getIIDForName(in string name); + string getNameForIID(in nsIIDPtr iid); + + nsIEnumerator enumerateInterfaces(); + + void autoRegisterInterfaces(); + + nsIEnumerator enumerateInterfacesWhoseNamesStartWith(in string prefix); +}; + +[uuid(0ee22850-bc6a-11d5-9134-0010a4e73d9a)] +interface nsIInterfaceInfoSuperManager : nsIInterfaceInfoManager +{ + void addAdditionalManager(in nsIInterfaceInfoManager manager); + void removeAdditionalManager(in nsIInterfaceInfoManager manager); + + PRBool hasAdditionalManagers(); + nsISimpleEnumerator enumerateAdditionalManagers(); +}; + +%{C++ +#define NS_INTERFACEINFOMANAGER_SERVICE_CLASSNAME \ + "Interface Information Manager Service" + +#define NS_INTERFACEINFOMANAGER_SERVICE_CID \ + { /* 13bef784-f8e0-4f96-85c1-09f9ef4f9a19 */ \ + 0x13bef784, 0xf8e0, 0x4f96, \ + {0x85, 0xc1, 0x09, 0xf9, 0xef, 0x4f, 0x9a, 0x19} } + +#define NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID \ + "@mozilla.org/xpti/interfaceinfomanager-service;1" +%} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/nsIXPTLoader.idl b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/nsIXPTLoader.idl new file mode 100644 index 00000000..8918daa3 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/nsIXPTLoader.idl @@ -0,0 +1,100 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the external XPT loader interface. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * John Bandhauer <jband@netscape.com> + * Alec Flett <alecf@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "nsISupports.idl" +#include "nsILocalFile.idl" +#include "nsIInputStream.idl" + +/** + * Implement nsIXPTLoaderSink if you want to enumerate the entries in + * an XPT archive of some kind + */ +[scriptable, uuid(6E48C500-8682-4730-ADD6-7DB693B9E7BA)] +interface nsIXPTLoaderSink : nsISupports { + + /** + * called by the loader for each entry in the archive + * @param itemName the name of this particular item in the archive + * @param index the index of the item inthe archive + * @param stream contains the contents of the xpt file + */ + void foundEntry(in string itemName, + in long index, + in nsIInputStream xptData); +}; + +/** + * The XPT loader interface: implemented by a loader to grab an input + * stream which will be consumed by the interface loader. + */ +[scriptable, uuid(368A15D9-17A9-4c2b-AC3D-A35B3A22B876)] +interface nsIXPTLoader : nsISupports { + /** + * enumerate entries in the given archive + * for each entry found, the loader will call the sink's + * foundEntry() method with the appropriate information and a + * stream that the consumer can read from + * @param file the file to read from + * @param sink an object which will be called with each file found + * in the file + */ + void enumerateEntries(in nsILocalFile file, + in nsIXPTLoaderSink sink ); + + /** + * Load a specific entry from the archive + * @param file the file to read from + * @param name the name of the xpt within the file + * @return an input stream that will read the raw xpt data from + * the file + */ + nsIInputStream loadEntry(in nsILocalFile file, + in string name); +}; + + +%{C++ + +// the first part of the contractID for any loader +// append the type of loader that you need, such as "zip" +#define NS_XPTLOADER_CONTRACTID_PREFIX \ + "@mozilla.org/xptinfo/loader;1&type=" + +%} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/xptinfo.h b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/xptinfo.h new file mode 100644 index 00000000..076482a6 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/public/xptinfo.h @@ -0,0 +1,281 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* XPTI_PUBLIC_API and XPTI_GetInterfaceInfoManager declarations. */ + +#ifndef xptiinfo_h___ +#define xptiinfo_h___ + +#include "prtypes.h" +#include "xpt_struct.h" + +#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP +#define XPTI_GetInterfaceInfoManager VBoxNsxpXPTI_GetInterfaceInfoManager +#define XPTI_FreeInterfaceInfoManager VBoxNsxpXPTI_FreeInterfaceInfoManager +#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */ + +/* + * The linkage of XPTI API functions differs depending on whether the file is + * used within the XPTI library or not. Any source file within the XPTI + * library should define EXPORT_XPTI_API whereas any client of the library + * should not. + */ +#ifdef EXPORT_XPTI_API +#define XPTI_PUBLIC_API(t) PR_IMPLEMENT(t) +#define XPTI_PUBLIC_DATA(t) PR_IMPLEMENT_DATA(t) +#if defined(_WIN32) +# define XPTI_EXPORT __declspec(dllexport) +#elif defined(XP_OS2) && defined(__declspec) +# define XPTI_EXPORT __declspec(dllexport) +#elif defined(XP_OS2_VACPP) +# define XPTI_EXPORT extern +#else +# define XPTI_EXPORT +#endif +#else +#if defined(_WIN32) +# define XPTI_PUBLIC_API(t) __declspec(dllimport) t +# define XPTI_PUBLIC_DATA(t) __declspec(dllimport) t +# define XPTI_EXPORT __declspec(dllimport) +#elif defined(XP_OS2) && defined(__declspec) +# define XPTI_PUBLIC_API(t) __declspec(dllimport) t +# define XPTI_PUBLIC_DATA(t) __declspec(dllimport) t +# define XPTI_EXPORT __declspec(dllimport) +#elif defined(XP_OS2_VACPP) +# define XPTI_PUBLIC_API(t) extern t +# define XPTI_PUBLIC_DATA(t) extern t +# define XPTI_EXPORT extern +#else +# define XPTI_PUBLIC_API(t) PR_IMPLEMENT(t) +# define XPTI_PUBLIC_DATA(t) t +# define XPTI_EXPORT +#endif +#endif +#define XPTI_FRIEND_API(t) XPTI_PUBLIC_API(t) +#define XPTI_FRIEND_DATA(t) XPTI_PUBLIC_DATA(t) + +class nsIInterfaceInfoManager; +PR_BEGIN_EXTERN_C +// Even if this is a service, it is cool to provide a direct accessor +XPTI_PUBLIC_API(nsIInterfaceInfoManager*) +XPTI_GetInterfaceInfoManager(); + +// Even if this is a service, it is cool to provide a direct accessor +XPTI_PUBLIC_API(void) +XPTI_FreeInterfaceInfoManager(); +PR_END_EXTERN_C + + + +// Flyweight wrapper classes for xpt_struct.h structs. +// Everything here is dependent upon - and sensitive to changes in - +// xpcom/typelib/xpt/public/xpt_struct.h! + +class nsXPTType : public XPTTypeDescriptorPrefix +{ +// NO DATA - this a flyweight wrapper +public: + nsXPTType() + {} // random contents + nsXPTType(const XPTTypeDescriptorPrefix& prefix) + {*(XPTTypeDescriptorPrefix*)this = prefix;} + + nsXPTType(const uint8& prefix) + {*(uint8*)this = prefix;} + + nsXPTType& operator=(uint8 val) + {flags = val; return *this;} + + nsXPTType& operator=(const nsXPTType& other) + {flags = other.flags; return *this;} + + operator uint8() const + {return flags;} + + PRBool IsPointer() const + {return 0 != (XPT_TDP_IS_POINTER(flags));} + + PRBool IsUniquePointer() const + {return 0 != (XPT_TDP_IS_UNIQUE_POINTER(flags));} + + PRBool IsReference() const + {return 0 != (XPT_TDP_IS_REFERENCE(flags));} + + PRBool IsArithmetic() const // terminology from Harbison/Steele + {return flags <= T_WCHAR;} + + PRBool IsInterfacePointer() const + { switch (TagPart()) { + default: + return PR_FALSE; + case T_INTERFACE: + case T_INTERFACE_IS: + return PR_TRUE; + } + } + + PRBool IsArray() const + {return (PRBool) TagPart() == T_ARRAY;} + + // 'Dependent' means that params of this type are dependent upon other + // params. e.g. an T_INTERFACE_IS is dependent upon some other param at + // runtime to say what the interface type of this param really is. + PRBool IsDependent() const + { switch (TagPart()) { + default: + return PR_FALSE; + case T_INTERFACE_IS: + case TD_ARRAY: + case T_PSTRING_SIZE_IS: + case T_PWSTRING_SIZE_IS: + return PR_TRUE; + } + } + + uint8 TagPart() const + {return (uint8) (flags & XPT_TDP_TAGMASK);} + + enum + { + T_I8 = TD_INT8 , + T_I16 = TD_INT16 , + T_I32 = TD_INT32 , + T_I64 = TD_INT64 , + T_U8 = TD_UINT8 , + T_U16 = TD_UINT16 , + T_U32 = TD_UINT32 , + T_U64 = TD_UINT64 , + T_FLOAT = TD_FLOAT , + T_DOUBLE = TD_DOUBLE , + T_BOOL = TD_BOOL , + T_CHAR = TD_CHAR , + T_WCHAR = TD_WCHAR , + T_VOID = TD_VOID , + T_IID = TD_PNSIID , + T_DOMSTRING = TD_DOMSTRING , + T_CHAR_STR = TD_PSTRING , + T_WCHAR_STR = TD_PWSTRING , + T_INTERFACE = TD_INTERFACE_TYPE , + T_INTERFACE_IS = TD_INTERFACE_IS_TYPE, + T_ARRAY = TD_ARRAY , + T_PSTRING_SIZE_IS = TD_PSTRING_SIZE_IS , + T_PWSTRING_SIZE_IS = TD_PWSTRING_SIZE_IS , + T_UTF8STRING = TD_UTF8STRING , + T_CSTRING = TD_CSTRING , + T_ASTRING = TD_ASTRING + }; +// NO DATA - this a flyweight wrapper +}; + +class nsXPTParamInfo : public XPTParamDescriptor +{ +// NO DATA - this a flyweight wrapper +public: + nsXPTParamInfo(const XPTParamDescriptor& desc) + {*(XPTParamDescriptor*)this = desc;} + + + PRBool IsIn() const {return 0 != (XPT_PD_IS_IN(flags));} + PRBool IsOut() const {return 0 != (XPT_PD_IS_OUT(flags));} + PRBool IsRetval() const {return 0 != (XPT_PD_IS_RETVAL(flags));} + PRBool IsShared() const {return 0 != (XPT_PD_IS_SHARED(flags));} + PRBool IsDipper() const {return 0 != (XPT_PD_IS_DIPPER(flags));} + const nsXPTType GetType() const {return type.prefix;} + + // NOTE: other activities on types are done via methods on nsIInterfaceInfo + +private: + nsXPTParamInfo(); // no implementation +// NO DATA - this a flyweight wrapper +}; + +class nsXPTMethodInfo : public XPTMethodDescriptor +{ +// NO DATA - this a flyweight wrapper +public: + nsXPTMethodInfo(const XPTMethodDescriptor& desc) + {*(XPTMethodDescriptor*)this = desc;} + + PRBool IsGetter() const {return 0 != (XPT_MD_IS_GETTER(flags) );} + PRBool IsSetter() const {return 0 != (XPT_MD_IS_SETTER(flags) );} + PRBool IsNotXPCOM() const {return 0 != (XPT_MD_IS_NOTXPCOM(flags));} + PRBool IsConstructor() const {return 0 != (XPT_MD_IS_CTOR(flags) );} + PRBool IsHidden() const {return 0 != (XPT_MD_IS_HIDDEN(flags) );} + const char* GetName() const {return name;} + uint8 GetParamCount() const {return num_args;} + /* idx was index before I got _sick_ of the warnings on Unix, sorry jband */ + const nsXPTParamInfo GetParam(uint8 idx) const + { + NS_PRECONDITION(idx < GetParamCount(),"bad arg"); + return params[idx]; + } + const nsXPTParamInfo GetResult() const + {return *result;} +private: + nsXPTMethodInfo(); // no implementation +// NO DATA - this a flyweight wrapper +}; + + +// forward declaration +struct nsXPTCMiniVariant; + +class nsXPTConstant : public XPTConstDescriptor +{ +// NO DATA - this a flyweight wrapper +public: + nsXPTConstant(const XPTConstDescriptor& desc) + {*(XPTConstDescriptor*)this = desc;} + + const char* GetName() const + {return name;} + + const nsXPTType GetType() const + {return type.prefix;} + + // XXX this is ugly. But sometimes you gotta do what you gotta do. + // A reinterpret_cast won't do the trick here. And this plain C cast + // works correctly and is safe enough. + // See http://bugzilla.mozilla.org/show_bug.cgi?id=49641 + const nsXPTCMiniVariant* GetValue() const + {return (nsXPTCMiniVariant*) &value;} +private: + nsXPTConstant(); // no implementation +// NO DATA - this a flyweight wrapper +}; + +#endif /* xptiinfo_h___ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/Makefile.in new file mode 100644 index 00000000..de5fd9b1 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/Makefile.in @@ -0,0 +1,75 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +LIBRARY_NAME = xptinfo +REQUIRES = \ + string \ + $(NULL) + +CPPSRCS = \ + xptiFile.cpp \ + xptiInterfaceInfo.cpp \ + xptiInterfaceInfoManager.cpp \ + xptiManifest.cpp \ + xptiMisc.cpp \ + xptiTypelibGuts.cpp \ + xptiWorkingSet.cpp \ + xptiZipItem.cpp \ + xptiZipLoader.cpp \ + $(NULL) + +# we don't want the shared lib, but we want to force the creation of a static lib. +FORCE_STATIC_LIB = 1 + +# Force use of PIC +FORCE_USE_PIC = 1 + +include $(topsrcdir)/config/rules.mk + +# For nsManifestLineReader class. +LOCAL_INCLUDES = -I$(srcdir)/../../../ds + +DEFINES += -DEXPORT_XPTI_API -DEXPORT_XPT_API -D_IMPL_NS_COM -D_IMPL_NS_BASE + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/TODO b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/TODO new file mode 100644 index 00000000..c5bb1c64 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/TODO @@ -0,0 +1,20 @@ +/* jband - 03/24/00 - */ + +- DOCS +- improve error handling + - should some errors really be warnings? + - should autoreg support additional channel to recieve warnings so that + an installer can decide whether or not to accept the consequences of + leaving the newly installed files in place? +- verification of interfaces (warnings and/or errors) + - verify that repeated interfaces are identical in all ways + - verify that interface names are always one-to-one with iids +- check for truncated xpt files and version problems + - http://bugzilla.mozilla.org/show_bug.cgi?id=33193 +- TESTS! + - e.g. verify the merge stuff really works for various inputs. + - we really need a set of .xpt and .zip files and code that does an array + of autoreg and interfaceinof use activitities to test various corners + of the system. +- better autoreg logging +- use only 32 bits for file size? diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiFile.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiFile.cpp new file mode 100644 index 00000000..50362c75 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiFile.cpp @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of xptiFile. */ + +#include "xptiprivate.h" + +MOZ_DECL_CTOR_COUNTER(xptiFile) + +xptiFile::xptiFile() + : +#ifdef DEBUG + mDEBUG_WorkingSet(nsnull), +#endif + mSize(), + mDate(), + mName(nsnull), + mGuts(nsnull), + mDirectory(0) +{ + // empty + MOZ_COUNT_CTOR(xptiFile); +} + +xptiFile::xptiFile(const nsInt64& aSize, + const nsInt64& aDate, + PRUint32 aDirectory, + const char* aName, + xptiWorkingSet* aWorkingSet) + : +#ifdef DEBUG + mDEBUG_WorkingSet(aWorkingSet), +#endif + mSize(aSize), + mDate(aDate), + mName(aName), + mGuts(nsnull), + mDirectory(aDirectory) +{ + NS_ASSERTION(aWorkingSet,"bad param"); + mName = XPT_STRDUP(aWorkingSet->GetStringArena(), aName); + + MOZ_COUNT_CTOR(xptiFile); +} + +xptiFile::xptiFile(const xptiFile& r, xptiWorkingSet* aWorkingSet) + : +#ifdef DEBUG + mDEBUG_WorkingSet(aWorkingSet), +#endif + mSize(r.mSize), + mDate(r.mDate), + mName(nsnull), + mGuts(nsnull), + mDirectory(r.mDirectory) +{ + NS_ASSERTION(aWorkingSet,"bad param"); + mName = XPT_STRDUP(aWorkingSet->GetStringArena(), r.mName); + + MOZ_COUNT_CTOR(xptiFile); +} + +xptiFile::~xptiFile() +{ + MOZ_COUNT_DTOR(xptiFile); +} + +PRBool +xptiFile::SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet) +{ + NS_ASSERTION(!mGuts,"bad state"); + NS_ASSERTION(aHeader,"bad param"); + NS_ASSERTION(aWorkingSet,"bad param"); + + mGuts = xptiTypelibGuts::NewGuts(aHeader, aWorkingSet); + return mGuts != nsnull; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp new file mode 100644 index 00000000..69bf86df --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp @@ -0,0 +1,819 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of xptiInterfaceEntry and xptiInterfaceInfo. */ + +#include "xptiprivate.h" + +/***************************************************************************/ +// Debug Instrumentation... + +#ifdef SHOW_INFO_COUNT_STATS +static int DEBUG_TotalInfos = 0; +static int DEBUG_CurrentInfos = 0; +static int DEBUG_MaxInfos = 0; +static int DEBUG_MonitorEntryCount = 0; + +#define LOG_INFO_CREATE(t) \ + DEBUG_TotalInfos++; \ + DEBUG_CurrentInfos++; \ + if(DEBUG_MaxInfos < DEBUG_CurrentInfos) \ + DEBUG_MaxInfos = DEBUG_CurrentInfos /* no ';' */ + +#define LOG_INFO_DESTROY(t) \ + DEBUG_CurrentInfos-- /* no ';' */ + +#define LOG_INFO_MONITOR_ENTRY \ + DEBUG_MonitorEntryCount++ /* no ';' */ + +#else /* SHOW_INFO_COUNT_STATS */ + +#define LOG_INFO_CREATE(t) ((void)0) +#define LOG_INFO_DESTROY(t) ((void)0) +#define LOG_INFO_MONITOR_ENTRY ((void)0) +#endif /* SHOW_INFO_COUNT_STATS */ + +#ifdef DEBUG +// static +void xptiInterfaceInfo::DEBUG_ShutdownNotification() +{ +#ifdef SHOW_INFO_COUNT_STATS + printf("iiii %d total xptiInterfaceInfos created\n", DEBUG_TotalInfos); + printf("iiii %d max xptiInterfaceInfos alive at one time\n", DEBUG_MaxInfos); + printf("iiii %d xptiInterfaceInfos still alive\n", DEBUG_CurrentInfos); + printf("iiii %d times locked\n", DEBUG_MonitorEntryCount); +#endif +} +#endif /* DEBUG */ + +/***************************************************************************/ + +// static +xptiInterfaceEntry* +xptiInterfaceEntry::NewEntry(const char* name, + int nameLength, + const nsID& iid, + const xptiTypelib& typelib, + xptiWorkingSet* aWorkingSet) +{ + void* place = XPT_MALLOC(aWorkingSet->GetStructArena(), + sizeof(xptiInterfaceEntry) + nameLength); + if(!place) + return nsnull; + return new(place) xptiInterfaceEntry(name, nameLength, iid, typelib); +} + +// static +xptiInterfaceEntry* +xptiInterfaceEntry::NewEntry(const xptiInterfaceEntry& r, + const xptiTypelib& typelib, + xptiWorkingSet* aWorkingSet) +{ + size_t nameLength = PL_strlen(r.mName); + void* place = XPT_MALLOC(aWorkingSet->GetStructArena(), + sizeof(xptiInterfaceEntry) + nameLength); + if(!place) + return nsnull; + return new(place) xptiInterfaceEntry(r, nameLength, typelib); +} + + +xptiInterfaceEntry::xptiInterfaceEntry(const char* name, + size_t nameLength, + const nsID& iid, + const xptiTypelib& typelib) + : mIID(iid), + mTypelib(typelib), + mInfo(nsnull), + mFlags(uint8(0)) +{ + memcpy(mName, name, nameLength); +} + +xptiInterfaceEntry::xptiInterfaceEntry(const xptiInterfaceEntry& r, + size_t nameLength, + const xptiTypelib& typelib) + : mIID(r.mIID), + mTypelib(typelib), + mInfo(nsnull), + mFlags(r.mFlags) +{ + SetResolvedState(NOT_RESOLVED); + memcpy(mName, r.mName, nameLength); +} + +PRBool +xptiInterfaceEntry::Resolve(xptiWorkingSet* aWorkingSet /* = nsnull */) +{ + nsAutoLock lock(xptiInterfaceInfoManager::GetResolveLock()); + return ResolveLocked(aWorkingSet); +} + +PRBool +xptiInterfaceEntry::ResolveLocked(xptiWorkingSet* aWorkingSet /* = nsnull */) +{ + int resolvedState = GetResolveState(); + + if(resolvedState == FULLY_RESOLVED) + return PR_TRUE; + if(resolvedState == RESOLVE_FAILED) + return PR_FALSE; + + xptiInterfaceInfoManager* mgr = + xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef(); + + if(!mgr) + return PR_FALSE; + + if(!aWorkingSet) + { + aWorkingSet = mgr->GetWorkingSet(); + } + + if(resolvedState == NOT_RESOLVED) + { + LOG_RESOLVE(("! begin resolve of %s\n", mName)); + // Make a copy of mTypelib because the underlying memory will change! + xptiTypelib typelib = mTypelib; + + // We expect our PartiallyResolveLocked() to get called before + // this returns. + if(!mgr->LoadFile(typelib, aWorkingSet)) + { + SetResolvedState(RESOLVE_FAILED); + return PR_FALSE; + } + // The state was changed by LoadFile to PARTIALLY_RESOLVED, so this + // ...falls through... + } + + NS_ASSERTION(GetResolveState() == PARTIALLY_RESOLVED, "bad state!"); + + // Finish out resolution by finding parent and Resolving it so + // we can set the info we get from it. + + PRUint16 parent_index = mInterface->mDescriptor->parent_interface; + + if(parent_index) + { + xptiInterfaceEntry* parent = + aWorkingSet->GetTypelibGuts(mInterface->mTypelib)-> + GetEntryAt(parent_index - 1); + + if(!parent || !parent->EnsureResolvedLocked()) + { + xptiTypelib aTypelib = mInterface->mTypelib; + mInterface = nsnull; + mTypelib = aTypelib; + SetResolvedState(RESOLVE_FAILED); + return PR_FALSE; + } + + mInterface->mParent = parent; + + mInterface->mMethodBaseIndex = + parent->mInterface->mMethodBaseIndex + + parent->mInterface->mDescriptor->num_methods; + + mInterface->mConstantBaseIndex = + parent->mInterface->mConstantBaseIndex + + parent->mInterface->mDescriptor->num_constants; + + } + LOG_RESOLVE(("+ complete resolve of %s\n", mName)); + + SetResolvedState(FULLY_RESOLVED); + return PR_TRUE; +} + +// This *only* gets called by xptiInterfaceInfoManager::LoadFile (while locked). +PRBool +xptiInterfaceEntry::PartiallyResolveLocked(XPTInterfaceDescriptor* aDescriptor, + xptiWorkingSet* aWorkingSet) +{ + NS_ASSERTION(GetResolveState() == NOT_RESOLVED, "bad state"); + + LOG_RESOLVE(("~ partial resolve of %s\n", mName)); + + xptiInterfaceGuts* iface = + xptiInterfaceGuts::NewGuts(aDescriptor, mTypelib, aWorkingSet); + + if(!iface) + return PR_FALSE; + + mInterface = iface; + +#ifdef DEBUG + if(!DEBUG_ScriptableFlagIsValid()) + { + NS_ERROR("unexpected scriptable flag!"); + SetScriptableFlag(XPT_ID_IS_SCRIPTABLE(mInterface->mDescriptor->flags)); + } +#endif + + SetResolvedState(PARTIALLY_RESOLVED); + return PR_TRUE; +} + +/**************************************************/ +// These non-virtual methods handle the delegated nsIInterfaceInfo methods. + +nsresult +xptiInterfaceEntry::GetName(char **name) +{ + // It is not necessary to Resolve because this info is read from manifest. + *name = (char*) nsMemory::Clone(mName, PL_strlen(mName)+1); + return *name ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +nsresult +xptiInterfaceEntry::GetIID(nsIID **iid) +{ + // It is not necessary to Resolve because this info is read from manifest. + *iid = (nsIID*) nsMemory::Clone(&mIID, sizeof(nsIID)); + return *iid ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +nsresult +xptiInterfaceEntry::IsScriptable(PRBool* result) +{ + // It is not necessary to Resolve because this info is read from manifest. + NS_ASSERTION(DEBUG_ScriptableFlagIsValid(), "scriptable flag out of sync!"); + *result = GetScriptableFlag(); + return NS_OK; +} + +nsresult +xptiInterfaceEntry::IsFunction(PRBool* result) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + *result = XPT_ID_IS_FUNCTION(GetInterfaceGuts()->mDescriptor->flags); + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetMethodCount(uint16* count) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + *count = mInterface->mMethodBaseIndex + + mInterface->mDescriptor->num_methods; + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetConstantCount(uint16* count) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + *count = mInterface->mConstantBaseIndex + + mInterface->mDescriptor->num_constants; + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetMethodInfo(uint16 index, const nsXPTMethodInfo** info) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + if(index < mInterface->mMethodBaseIndex) + return mInterface->mParent->GetMethodInfo(index, info); + + if(index >= mInterface->mMethodBaseIndex + + mInterface->mDescriptor->num_methods) + { + NS_ERROR("bad param"); + *info = NULL; + return NS_ERROR_INVALID_ARG; + } + + // else... + *info = NS_REINTERPRET_CAST(nsXPTMethodInfo*, + &mInterface->mDescriptor-> + method_descriptors[index - + mInterface->mMethodBaseIndex]); + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetMethodInfoForName(const char* methodName, uint16 *index, + const nsXPTMethodInfo** result) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + // This is a slow algorithm, but this is not expected to be called much. + for(uint16 i = 0; i < mInterface->mDescriptor->num_methods; ++i) + { + const nsXPTMethodInfo* info; + info = NS_REINTERPRET_CAST(nsXPTMethodInfo*, + &mInterface->mDescriptor-> + method_descriptors[i]); + if (PL_strcmp(methodName, info->GetName()) == 0) { + *index = i + mInterface->mMethodBaseIndex; + *result = info; + return NS_OK; + } + } + + if(mInterface->mParent) + return mInterface->mParent->GetMethodInfoForName(methodName, index, result); + else + { + *index = 0; + *result = 0; + return NS_ERROR_INVALID_ARG; + } +} + +nsresult +xptiInterfaceEntry::GetConstant(uint16 index, const nsXPTConstant** constant) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + if(index < mInterface->mConstantBaseIndex) + return mInterface->mParent->GetConstant(index, constant); + + if(index >= mInterface->mConstantBaseIndex + + mInterface->mDescriptor->num_constants) + { + NS_PRECONDITION(0, "bad param"); + *constant = NULL; + return NS_ERROR_INVALID_ARG; + } + + // else... + *constant = + NS_REINTERPRET_CAST(nsXPTConstant*, + &mInterface->mDescriptor-> + const_descriptors[index - + mInterface->mConstantBaseIndex]); + return NS_OK; +} + +// this is a private helper + +nsresult +xptiInterfaceEntry::GetEntryForParam(PRUint16 methodIndex, + const nsXPTParamInfo * param, + xptiInterfaceEntry** entry) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + if(methodIndex < mInterface->mMethodBaseIndex) + return mInterface->mParent->GetEntryForParam(methodIndex, param, entry); + + if(methodIndex >= mInterface->mMethodBaseIndex + + mInterface->mDescriptor->num_methods) + { + NS_ERROR("bad param"); + return NS_ERROR_INVALID_ARG; + } + + const XPTTypeDescriptor *td = ¶m->type; + + while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) { + td = &mInterface->mDescriptor->additional_types[td->type.additional_type]; + } + + if(XPT_TDP_TAG(td->prefix) != TD_INTERFACE_TYPE) { + NS_ERROR("not an interface"); + return NS_ERROR_INVALID_ARG; + } + + xptiInterfaceEntry* theEntry = + mInterface->mWorkingSet->GetTypelibGuts(mInterface->mTypelib)-> + GetEntryAt(td->type.iface - 1); + + // This can happen if a declared interface is not available at runtime. + if(!theEntry) + { + NS_WARNING("Declared InterfaceInfo not found"); + *entry = nsnull; + return NS_ERROR_FAILURE; + } + + *entry = theEntry; + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetInfoForParam(uint16 methodIndex, + const nsXPTParamInfo *param, + nsIInterfaceInfo** info) +{ + xptiInterfaceEntry* entry; + nsresult rv = GetEntryForParam(methodIndex, param, &entry); + if(NS_FAILED(rv)) + return rv; + + xptiInterfaceInfo* theInfo; + rv = entry->GetInterfaceInfo(&theInfo); + if(NS_FAILED(rv)) + return rv; + + *info = NS_STATIC_CAST(nsIInterfaceInfo*, theInfo); + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetIIDForParam(uint16 methodIndex, + const nsXPTParamInfo* param, nsIID** iid) +{ + xptiInterfaceEntry* entry; + nsresult rv = GetEntryForParam(methodIndex, param, &entry); + if(NS_FAILED(rv)) + return rv; + return entry->GetIID(iid); +} + +nsresult +xptiInterfaceEntry::GetIIDForParamNoAlloc(PRUint16 methodIndex, + const nsXPTParamInfo * param, + nsIID *iid) +{ + xptiInterfaceEntry* entry; + nsresult rv = GetEntryForParam(methodIndex, param, &entry); + if(NS_FAILED(rv)) + return rv; + *iid = entry->mIID; + return NS_OK; +} + +// this is a private helper +nsresult +xptiInterfaceEntry::GetTypeInArray(const nsXPTParamInfo* param, + uint16 dimension, + const XPTTypeDescriptor** type) +{ + NS_ASSERTION(IsFullyResolved(), "bad state"); + + const XPTTypeDescriptor *td = ¶m->type; + const XPTTypeDescriptor *additional_types = + mInterface->mDescriptor->additional_types; + + for (uint16 i = 0; i < dimension; i++) { + if(XPT_TDP_TAG(td->prefix) != TD_ARRAY) { + NS_ERROR("bad dimension"); + return NS_ERROR_INVALID_ARG; + } + td = &additional_types[td->type.additional_type]; + } + + *type = td; + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetTypeForParam(uint16 methodIndex, + const nsXPTParamInfo* param, + uint16 dimension, + nsXPTType* type) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + if(methodIndex < mInterface->mMethodBaseIndex) + return mInterface->mParent-> + GetTypeForParam(methodIndex, param, dimension, type); + + if(methodIndex >= mInterface->mMethodBaseIndex + + mInterface->mDescriptor->num_methods) + { + NS_ERROR("bad index"); + return NS_ERROR_INVALID_ARG; + } + + const XPTTypeDescriptor *td; + + if(dimension) { + nsresult rv = GetTypeInArray(param, dimension, &td); + if(NS_FAILED(rv)) + return rv; + } + else + td = ¶m->type; + + *type = nsXPTType(td->prefix); + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetSizeIsArgNumberForParam(uint16 methodIndex, + const nsXPTParamInfo* param, + uint16 dimension, + uint8* argnum) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + if(methodIndex < mInterface->mMethodBaseIndex) + return mInterface->mParent-> + GetSizeIsArgNumberForParam(methodIndex, param, dimension, argnum); + + if(methodIndex >= mInterface->mMethodBaseIndex + + mInterface->mDescriptor->num_methods) + { + NS_ERROR("bad index"); + return NS_ERROR_INVALID_ARG; + } + + const XPTTypeDescriptor *td; + + if(dimension) { + nsresult rv = GetTypeInArray(param, dimension, &td); + if(NS_FAILED(rv)) + return rv; + } + else + td = ¶m->type; + + // verify that this is a type that has size_is + switch (XPT_TDP_TAG(td->prefix)) { + case TD_ARRAY: + case TD_PSTRING_SIZE_IS: + case TD_PWSTRING_SIZE_IS: + break; + default: + NS_ERROR("not a size_is"); + return NS_ERROR_INVALID_ARG; + } + + *argnum = td->argnum; + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetLengthIsArgNumberForParam(uint16 methodIndex, + const nsXPTParamInfo* param, + uint16 dimension, + uint8* argnum) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + if(methodIndex < mInterface->mMethodBaseIndex) + return mInterface->mParent-> + GetLengthIsArgNumberForParam(methodIndex, param, dimension, argnum); + + if(methodIndex >= mInterface->mMethodBaseIndex + + mInterface->mDescriptor->num_methods) + { + NS_ERROR("bad index"); + return NS_ERROR_INVALID_ARG; + } + + const XPTTypeDescriptor *td; + + if(dimension) { + nsresult rv = GetTypeInArray(param, dimension, &td); + if(NS_FAILED(rv)) { + return rv; + } + } + else + td = ¶m->type; + + // verify that this is a type that has length_is + switch (XPT_TDP_TAG(td->prefix)) { + case TD_ARRAY: + case TD_PSTRING_SIZE_IS: + case TD_PWSTRING_SIZE_IS: + break; + default: + NS_ERROR("not a length_is"); + return NS_ERROR_INVALID_ARG; + } + + *argnum = td->argnum2; + return NS_OK; +} + +nsresult +xptiInterfaceEntry::GetInterfaceIsArgNumberForParam(uint16 methodIndex, + const nsXPTParamInfo* param, + uint8* argnum) +{ + if(!EnsureResolved()) + return NS_ERROR_UNEXPECTED; + + if(methodIndex < mInterface->mMethodBaseIndex) + return mInterface->mParent-> + GetInterfaceIsArgNumberForParam(methodIndex, param, argnum); + + if(methodIndex >= mInterface->mMethodBaseIndex + + mInterface->mDescriptor->num_methods) + { + NS_ERROR("bad index"); + return NS_ERROR_INVALID_ARG; + } + + const XPTTypeDescriptor *td = ¶m->type; + + while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) { + td = &mInterface->mDescriptor-> + additional_types[td->type.additional_type]; + } + + if(XPT_TDP_TAG(td->prefix) != TD_INTERFACE_IS_TYPE) { + NS_ERROR("not an iid_is"); + return NS_ERROR_INVALID_ARG; + } + + *argnum = td->argnum; + return NS_OK; +} + +/* PRBool isIID (in nsIIDPtr IID); */ +nsresult +xptiInterfaceEntry::IsIID(const nsIID * IID, PRBool *_retval) +{ + // It is not necessary to Resolve because this info is read from manifest. + *_retval = mIID.Equals(*IID); + return NS_OK; +} + +/* void getNameShared ([shared, retval] out string name); */ +nsresult +xptiInterfaceEntry::GetNameShared(const char **name) +{ + // It is not necessary to Resolve because this info is read from manifest. + *name = mName; + return NS_OK; +} + +/* void getIIDShared ([shared, retval] out nsIIDPtrShared iid); */ +nsresult +xptiInterfaceEntry::GetIIDShared(const nsIID * *iid) +{ + // It is not necessary to Resolve because this info is read from manifest. + *iid = &mIID; + return NS_OK; +} + +/* PRBool hasAncestor (in nsIIDPtr iid); */ +nsresult +xptiInterfaceEntry::HasAncestor(const nsIID * iid, PRBool *_retval) +{ + *_retval = PR_FALSE; + + for(xptiInterfaceEntry* current = this; + current; + current = current->mInterface->mParent) + { + if(current->mIID.Equals(*iid)) + { + *_retval = PR_TRUE; + break; + } + if(!current->EnsureResolved()) + return NS_ERROR_UNEXPECTED; + } + + return NS_OK; +} + +/***************************************************/ + +nsresult +xptiInterfaceEntry::GetInterfaceInfo(xptiInterfaceInfo** info) +{ + nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor()); + LOG_INFO_MONITOR_ENTRY; + +#ifdef SHOW_INFO_COUNT_STATS + static int callCount = 0; + if(!(++callCount%100)) + printf("iiii %d xptiInterfaceInfos currently alive\n", DEBUG_CurrentInfos); +#endif + + if(!mInfo) + { + mInfo = new xptiInterfaceInfo(this); + if(!mInfo) + { + *info = nsnull; + return NS_ERROR_OUT_OF_MEMORY; + } + } + + NS_ADDREF(*info = mInfo); + return NS_OK; +} + +void +xptiInterfaceEntry::LockedInvalidateInterfaceInfo() +{ + if(mInfo) + { + mInfo->Invalidate(); + mInfo = nsnull; + } +} + +/***************************************************************************/ + +NS_IMPL_QUERY_INTERFACE1(xptiInterfaceInfo, nsIInterfaceInfo) + +xptiInterfaceInfo::xptiInterfaceInfo(xptiInterfaceEntry* entry) + : mEntry(entry), mParent(nsnull) +{ + LOG_INFO_CREATE(this); +} + +xptiInterfaceInfo::~xptiInterfaceInfo() +{ + LOG_INFO_DESTROY(this); + NS_IF_RELEASE(mParent); + NS_ASSERTION(!mEntry, "bad state in dtor"); +} + +nsrefcnt +xptiInterfaceInfo::AddRef(void) +{ + nsrefcnt cnt = (nsrefcnt) PR_AtomicIncrement((PRInt32*)&mRefCnt); + NS_LOG_ADDREF(this, cnt, "xptiInterfaceInfo", sizeof(*this)); + return cnt; +} + +nsrefcnt +xptiInterfaceInfo::Release(void) +{ + xptiInterfaceEntry* entry = mEntry; + nsrefcnt cnt = (nsrefcnt) PR_AtomicDecrement((PRInt32*)&mRefCnt); + NS_LOG_RELEASE(this, cnt, "xptiInterfaceInfo"); + if(!cnt) + { + nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor()); + LOG_INFO_MONITOR_ENTRY; + + // If GetInterfaceInfo added and *released* a reference before we + // acquired the monitor then 'this' might already be dead. In that + // case we would not want to try to access any instance data. We + // would want to bail immediately. If 'this' is already dead then the + // entry will no longer have a pointer to 'this'. So, we can protect + // ourselves from danger without more aggressive locking. + if(entry && !entry->InterfaceInfoEquals(this)) + return 0; + + // If GetInterfaceInfo added a reference before we acquired the monitor + // then we want to bail out of here without destorying the object. + if(mRefCnt) + return 1; + + if(mEntry) + { + mEntry->LockedInterfaceInfoDeathNotification(); + mEntry = nsnull; + } + + NS_DELETEXPCOM(this); + return 0; + } + return cnt; +} + +/***************************************************************************/ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp new file mode 100644 index 00000000..5ae06914 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp @@ -0,0 +1,2126 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of xptiInterfaceInfoManager. */ + +#include "xptiprivate.h" +#include "nsDependentString.h" +#include "nsString.h" + +#define NS_ZIPLOADER_CONTRACTID NS_XPTLOADER_CONTRACTID_PREFIX "zip" + +NS_IMPL_THREADSAFE_ISUPPORTS2(xptiInterfaceInfoManager, + nsIInterfaceInfoManager, + nsIInterfaceInfoSuperManager) + +static xptiInterfaceInfoManager* gInterfaceInfoManager = nsnull; +#ifdef DEBUG +static int gCallCount = 0; +#endif + +// static +xptiInterfaceInfoManager* +xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef() +{ + if(!gInterfaceInfoManager) + { + nsCOMPtr<nsISupportsArray> searchPath; + BuildFileSearchPath(getter_AddRefs(searchPath)); + if(!searchPath) + { + NS_ERROR("can't get xpt search path!"); + return nsnull; + } + + gInterfaceInfoManager = new xptiInterfaceInfoManager(searchPath); + if(gInterfaceInfoManager) + NS_ADDREF(gInterfaceInfoManager); + if(!gInterfaceInfoManager->IsValid()) + { + NS_RELEASE(gInterfaceInfoManager); + } + else + { + PRBool mustAutoReg = + !xptiManifest::Read(gInterfaceInfoManager, + &gInterfaceInfoManager->mWorkingSet); +#ifdef DEBUG + { + // This sets what will be returned by GetOpenLogFile(). + xptiAutoLog autoLog(gInterfaceInfoManager, + gInterfaceInfoManager->mAutoRegLogFile, PR_TRUE); + LOG_AUTOREG(("debug build forced autoreg after %s load of manifest\n", mustAutoReg ? "FAILED" : "successful")); + + mustAutoReg = PR_TRUE; + } +#endif // DEBUG + if(mustAutoReg) + gInterfaceInfoManager->AutoRegisterInterfaces(); + } + } + return gInterfaceInfoManager; +} + +void +xptiInterfaceInfoManager::FreeInterfaceInfoManager() +{ + if(gInterfaceInfoManager) + gInterfaceInfoManager->LogStats(); + + NS_IF_RELEASE(gInterfaceInfoManager); +} + +PRBool +xptiInterfaceInfoManager::IsValid() +{ + return mWorkingSet.IsValid() && + mResolveLock && + mAutoRegLock && + mInfoMonitor && + mAdditionalManagersLock; +} + +xptiInterfaceInfoManager::xptiInterfaceInfoManager(nsISupportsArray* aSearchPath) + : mWorkingSet(aSearchPath), + mOpenLogFile(nsnull), + mResolveLock(PR_NewLock()), + mAutoRegLock(PR_NewLock()), + mInfoMonitor(nsAutoMonitor::NewMonitor("xptiInfoMonitor")), + mAdditionalManagersLock(PR_NewLock()), + mSearchPath(aSearchPath) +{ + const char* statsFilename = PR_GetEnv("MOZILLA_XPTI_STATS"); + if(statsFilename) + { + mStatsLogFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID); + if(mStatsLogFile && + NS_SUCCEEDED(mStatsLogFile->InitWithNativePath(nsDependentCString(statsFilename)))) + { + printf("* Logging xptinfo stats to: %s\n", statsFilename); + } + else + { + printf("* Failed to create xptinfo stats file: %s\n", statsFilename); + mStatsLogFile = nsnull; + } + } + + const char* autoRegFilename = PR_GetEnv("MOZILLA_XPTI_REGLOG"); + if(autoRegFilename) + { + mAutoRegLogFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID); + if(mAutoRegLogFile && + NS_SUCCEEDED(mAutoRegLogFile->InitWithNativePath(nsDependentCString(autoRegFilename)))) + { + printf("* Logging xptinfo autoreg to: %s\n", autoRegFilename); + } + else + { + printf("* Failed to create xptinfo autoreg file: %s\n", autoRegFilename); + mAutoRegLogFile = nsnull; + } + } +} + +xptiInterfaceInfoManager::~xptiInterfaceInfoManager() +{ + // We only do this on shutdown of the service. + mWorkingSet.InvalidateInterfaceInfos(); + + if(mResolveLock) + PR_DestroyLock(mResolveLock); + if(mAutoRegLock) + PR_DestroyLock(mAutoRegLock); + if(mInfoMonitor) + nsAutoMonitor::DestroyMonitor(mInfoMonitor); + if(mAdditionalManagersLock) + PR_DestroyLock(mAdditionalManagersLock); + + gInterfaceInfoManager = nsnull; +#ifdef DEBUG + xptiInterfaceInfo::DEBUG_ShutdownNotification(); + gCallCount = 0; +#endif +} + +static nsresult +GetDirectoryFromDirService(const char* codename, nsILocalFile** aDir) +{ + NS_ASSERTION(codename,"loser!"); + NS_ASSERTION(aDir,"loser!"); + + nsresult rv; + nsCOMPtr<nsIProperties> dirService = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) return rv; + + return dirService->Get(codename, NS_GET_IID(nsILocalFile), (void**) aDir); +} + +static PRBool +AppendFromDirServiceList(const char* codename, nsISupportsArray* aPath) +{ + NS_ASSERTION(codename,"loser!"); + NS_ASSERTION(aPath,"loser!"); + + nsCOMPtr<nsIProperties> dirService = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID); + if(!dirService) + return PR_FALSE; + + nsCOMPtr<nsISimpleEnumerator> fileList; + dirService->Get(codename, NS_GET_IID(nsISimpleEnumerator), + getter_AddRefs(fileList)); + if(!fileList) + return PR_FALSE; + + PRBool more; + while(NS_SUCCEEDED(fileList->HasMoreElements(&more)) && more) + { + nsCOMPtr<nsILocalFile> dir; + fileList->GetNext(getter_AddRefs(dir)); + if(!dir || !aPath->AppendElement(dir)) + return PR_FALSE; + } + + return PR_TRUE; +} + +// static +PRBool xptiInterfaceInfoManager::BuildFileSearchPath(nsISupportsArray** aPath) +{ +#ifdef DEBUG + NS_ASSERTION(!gCallCount++, "Expected only one call!"); +#endif + + nsCOMPtr<nsISupportsArray> searchPath; + NS_NewISupportsArray(getter_AddRefs(searchPath)); + if(!searchPath) + return PR_FALSE; + + nsCOMPtr<nsILocalFile> compDir; + + // Always put components directory first + + if(NS_FAILED(GetDirectoryFromDirService(NS_XPCOM_COMPONENT_DIR, + getter_AddRefs(compDir))) || + !searchPath->AppendElement(compDir)) + { + return PR_FALSE; + } + + // Add additional plugins dirs + // No error checking here since this is optional in some embeddings + + // Add the GRE's component directory to searchPath if the + // application is using an GRE. + // An application indicates that it's using an GRE by returning + // a valid nsIFile via it's directory service provider interface. + // + // Please see http://www.mozilla.org/projects/embedding/MRE.html + // for more info. on GREs + // + nsCOMPtr<nsILocalFile> greComponentDirectory; + nsresult rv = GetDirectoryFromDirService(NS_GRE_COMPONENT_DIR, + getter_AddRefs(greComponentDirectory)); + if(NS_SUCCEEDED(rv) && greComponentDirectory) + { + // make sure we only append a directory if its a different one + PRBool equalsCompDir = PR_FALSE; + greComponentDirectory->Equals(compDir, &equalsCompDir); + + if(!equalsCompDir) + searchPath->AppendElement(greComponentDirectory); + } + + (void)AppendFromDirServiceList(NS_XPCOM_COMPONENT_DIR_LIST, searchPath); + (void)AppendFromDirServiceList(NS_APP_PLUGINS_DIR_LIST, searchPath); + + NS_ADDREF(*aPath = searchPath); + return PR_TRUE; +} + +PRBool +xptiInterfaceInfoManager::GetCloneOfManifestLocation(nsILocalFile** aFile) +{ + // We *trust* that this will not change! + nsCOMPtr<nsILocalFile> lf; + nsresult rv = GetDirectoryFromDirService(NS_XPCOM_XPTI_REGISTRY_FILE, + getter_AddRefs(lf)); + + if (NS_FAILED(rv)) return PR_FALSE; + + rv = xptiCloneLocalFile(lf, aFile); + if (NS_FAILED(rv)) return PR_FALSE; + return PR_TRUE; +} + +PRBool +xptiInterfaceInfoManager::GetApplicationDir(nsILocalFile** aDir) +{ + // We *trust* that this will not change! + return NS_SUCCEEDED(GetDirectoryFromDirService(NS_XPCOM_CURRENT_PROCESS_DIR, aDir)); +} + +PRBool +xptiInterfaceInfoManager::BuildFileList(nsISupportsArray* aSearchPath, + nsISupportsArray** aFileList) +{ + NS_ASSERTION(aFileList, "loser!"); + + nsresult rv; + + nsCOMPtr<nsISupportsArray> fileList = + do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID); + if(!fileList) + return PR_FALSE; + + PRUint32 pathCount; + if(NS_FAILED(aSearchPath->Count(&pathCount))) + return PR_FALSE; + + for(PRUint32 i = 0; i < pathCount; i++) + { + nsCOMPtr<nsILocalFile> dir; + rv = xptiCloneElementAsLocalFile(aSearchPath, i, getter_AddRefs(dir)); + if(NS_FAILED(rv) || !dir) + return PR_FALSE; + + nsCOMPtr<nsISimpleEnumerator> entries; + rv = dir->GetDirectoryEntries(getter_AddRefs(entries)); + if(NS_FAILED(rv) || !entries) + continue; + + PRUint32 count = 0; + PRBool hasMore; + while(NS_SUCCEEDED(entries->HasMoreElements(&hasMore)) && hasMore) + { + nsCOMPtr<nsISupports> sup; + entries->GetNext(getter_AddRefs(sup)); + if(!sup) + return PR_FALSE; + nsCOMPtr<nsILocalFile> file = do_QueryInterface(sup); + if(!file) + return PR_FALSE; + + PRBool isFile; + if(NS_FAILED(file->IsFile(&isFile)) || !isFile) + { + continue; + } + + nsCAutoString name; + if(NS_FAILED(file->GetNativeLeafName(name))) + return PR_FALSE; + + if(xptiFileType::IsUnknown(name.get())) + continue; + + LOG_AUTOREG(("found file: %s\n", name.get())); + + if(!fileList->InsertElementAt(file, count)) + return PR_FALSE; + ++count; + } + } + + NS_ADDREF(*aFileList = fileList); + return PR_TRUE; +} + +XPTHeader* +xptiInterfaceInfoManager::ReadXPTFile(nsILocalFile* aFile, + xptiWorkingSet* aWorkingSet) +{ + NS_ASSERTION(aFile, "loser!"); + + XPTHeader *header = nsnull; + char *whole = nsnull; + PRFileDesc* fd = nsnull; + XPTState *state = nsnull; + XPTCursor cursor; + PRInt32 flen; + PRInt64 fileSize; + + PRBool saveFollowLinks; + aFile->GetFollowLinks(&saveFollowLinks); + aFile->SetFollowLinks(PR_TRUE); + + if(NS_FAILED(aFile->GetFileSize(&fileSize)) || !(flen = nsInt64(fileSize))) + { + aFile->SetFollowLinks(saveFollowLinks); + return nsnull; + } + + whole = new char[flen]; + if (!whole) + { + aFile->SetFollowLinks(saveFollowLinks); + return nsnull; + } + + // all exits from on here should be via 'goto out' + + if(NS_FAILED(aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd)) || !fd) + { + goto out; + } + + if(flen > PR_Read(fd, whole, flen)) + { + goto out; + } + + if(!(state = XPT_NewXDRState(XPT_DECODE, whole, flen))) + { + goto out; + } + + if(!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor)) + { + goto out; + } + + if (!XPT_DoHeader(aWorkingSet->GetStructArena(), &cursor, &header)) + { + header = nsnull; + goto out; + } + + out: + if(fd) + PR_Close(fd); + if(state) + XPT_DestroyXDRState(state); + if(whole) + delete [] whole; + aFile->SetFollowLinks(saveFollowLinks); + return header; +} + +PRBool +xptiInterfaceInfoManager::LoadFile(const xptiTypelib& aTypelibRecord, + xptiWorkingSet* aWorkingSet) +{ + if(!aWorkingSet) + aWorkingSet = &mWorkingSet; + + if(!aWorkingSet->IsValid()) + return PR_FALSE; + + xptiFile* fileRecord = &aWorkingSet->GetFileAt(aTypelibRecord.GetFileIndex()); + xptiZipItem* zipItem = nsnull; + + nsCOMPtr<nsILocalFile> file; + if(NS_FAILED(aWorkingSet->GetCloneOfDirectoryAt(fileRecord->GetDirectory(), + getter_AddRefs(file))) || !file) + return PR_FALSE; + + if(NS_FAILED(file->AppendNative(nsDependentCString(fileRecord->GetName())))) + return PR_FALSE; + + XPTHeader* header; + + if(aTypelibRecord.IsZip()) + { + zipItem = &aWorkingSet->GetZipItemAt(aTypelibRecord.GetZipItemIndex()); + + // See the big comment below in the 'non-zip' case... + if(zipItem->GetGuts()) + { + NS_ERROR("Trying to load an xpt file from a zip twice"); + + // Force an autoreg on next run + (void) xptiManifest::Delete(this); + + return PR_FALSE; + } + + LOG_LOAD(("# loading zip item %s::%s\n", fileRecord->GetName(), zipItem->GetName())); + + nsCOMPtr<nsIXPTLoader> loader = + do_GetService(NS_ZIPLOADER_CONTRACTID); + + if (loader) { + nsresult rv; + + nsCOMPtr<nsIInputStream> stream; + rv = loader->LoadEntry(file, zipItem->GetName(), + getter_AddRefs(stream)); + + if (NS_FAILED(rv)) + return PR_FALSE; + + header = + xptiZipLoader::ReadXPTFileFromInputStream(stream, aWorkingSet); + } else { + header = nsnull; + NS_WARNING("Could not load XPT Zip loader"); + } + } + else + { + // The file would only have guts already if we previously failed to + // find an interface info in a file where the manifest claimed it was + // going to be. + // + // Normally, when the file gets loaded (and the guts set) then all + // interfaces would also be resolved. So, if we are here again for + // the same file then there must have been some interface that was + // expected but not present. Now we are explicitly trying to find it + // and it isn't going to be there this time either. + // + // This is an assertion style error in a DEBUG build because it shows + // that we failed to detect this in autoreg. For release builds (where + // autoreg is not run on every startup) it is just bad. But by returning + // PR_FALSE we mark this interface as RESOLVE_FAILED and get on with + // things without crashing or anything. + // + // We don't want to do an autoreg here because this is too much of an + // edge case (and in that odd case it might autoreg multiple times if + // many interfaces had been removed). But, by deleting the manifest we + // force the system to get it right on the next run. + + if(fileRecord->GetGuts()) + { + NS_ERROR("Trying to load an xpt file twice"); + + // Force an autoreg on next run + (void) xptiManifest::Delete(this); + + return PR_FALSE; + } + + LOG_LOAD(("^ loading file %s\n", fileRecord->GetName())); + header = ReadXPTFile(file, aWorkingSet); + } + + if(!header) + return PR_FALSE; + + + if(aTypelibRecord.IsZip()) + { + // This also allocs zipItem.GetGuts() used below. + if(!zipItem->SetHeader(header, aWorkingSet)) + return PR_FALSE; + } + else + { + // This also allocs fileRecord.GetGuts() used below. + if(!fileRecord->SetHeader(header, aWorkingSet)) + return PR_FALSE; + } + + // For each interface in the header we want to find the xptiInterfaceInfo + // object and set its resolution info. + + for(PRUint16 i = 0; i < header->num_interfaces; i++) + { + static const nsID zeroIID = + { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; + + XPTInterfaceDirectoryEntry* iface = header->interface_directory + i; + + xptiHashEntry* hashEntry; + + if(!iface->iid.Equals(zeroIID)) + { + hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aWorkingSet->mIIDTable, + &iface->iid, PL_DHASH_LOOKUP); + } + else + { + hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aWorkingSet->mNameTable, + iface->name, PL_DHASH_LOOKUP); + } + + xptiInterfaceEntry* entry = + PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value; + + if(!entry) + { + // This one is just not resolved anywhere! + continue; + } + + if(aTypelibRecord.IsZip()) + zipItem->GetGuts()->SetEntryAt(i, entry); + else + fileRecord->GetGuts()->SetEntryAt(i, entry); + + XPTInterfaceDescriptor* descriptor = iface->interface_descriptor; + + if(descriptor && aTypelibRecord.Equals(entry->GetTypelibRecord())) + entry->PartiallyResolveLocked(descriptor, aWorkingSet); + } + return PR_TRUE; +} + +static int +IndexOfFileWithName(const char* aName, const xptiWorkingSet* aWorkingSet) +{ + NS_ASSERTION(aName, "loser!"); + + for(PRUint32 i = 0; i < aWorkingSet->GetFileCount(); ++i) + { + if(0 == PL_strcmp(aName, aWorkingSet->GetFileAt(i).GetName())) + return i; + } + return -1; +} + +static int +IndexOfDirectoryOfFile(nsISupportsArray* aSearchPath, nsILocalFile* aFile) +{ + nsCOMPtr<nsIFile> parent; + aFile->GetParent(getter_AddRefs(parent)); + if(parent) + { + PRUint32 count = 0; + aSearchPath->Count(&count); + NS_ASSERTION(count, "broken search path! bad count"); + for(PRUint32 i = 0; i < count; i++) + { + nsCOMPtr<nsIFile> current; + aSearchPath->QueryElementAt(i, NS_GET_IID(nsIFile), + getter_AddRefs(current)); + NS_ASSERTION(current, "broken search path! bad element"); + PRBool same; + if(NS_SUCCEEDED(parent->Equals(current, &same)) && same) + return (int) i; + } + } + NS_ERROR("file not in search directory!"); + return -1; +} + +struct SortData +{ + nsISupportsArray* mSearchPath; + xptiWorkingSet* mWorkingSet; +}; + +PR_STATIC_CALLBACK(int) +xptiSortFileList(const void * p1, const void *p2, void * closure) +{ + nsILocalFile* pFile1 = *((nsILocalFile**) p1); + nsILocalFile* pFile2 = *((nsILocalFile**) p2); + SortData* data = (SortData*) closure; + + nsCAutoString name1; + nsCAutoString name2; + + if(NS_FAILED(pFile1->GetNativeLeafName(name1))) + { + NS_ERROR("way bad, with no happy out!"); + return 0; + } + if(NS_FAILED(pFile2->GetNativeLeafName(name2))) + { + NS_ERROR("way bad, with no happy out!"); + return 0; + } + + int index1 = IndexOfFileWithName(name1.get(), data->mWorkingSet); + int index2 = IndexOfFileWithName(name2.get(), data->mWorkingSet); + + // Get these now in case we need them later. + PRBool isXPT1 = xptiFileType::IsXPT(name1.get()); + PRBool isXPT2 = xptiFileType::IsXPT(name2.get()); + int nameOrder = Compare(name1, name2); + + // both in workingSet, preserve old order + if(index1 != -1 && index2 != -1) + return index1 - index2; + + if(index1 != -1) + return 1; + + if(index2 != -1) + return -1; + + // neither is in workingset + + // check how they compare in search path order + + int dirIndex1 = IndexOfDirectoryOfFile(data->mSearchPath, pFile1); + int dirIndex2 = IndexOfDirectoryOfFile(data->mSearchPath, pFile2); + + if(dirIndex1 != dirIndex2) + return dirIndex1 - dirIndex2; + + // .xpt files come before archives (.zip, .jar, etc) + if(isXPT1 &&!isXPT2) + return -1; + + if(!isXPT1 && isXPT2) + return 1; + + // neither element is in the workingSet and both are same type and in + // the same directory, sort by size + + PRInt64 size1; + PRInt64 size2; + + if(NS_FAILED(pFile1->GetFileSize(&size1))) + { + NS_ERROR("way bad, with no happy out!"); + return 0; + } + if(NS_FAILED(pFile2->GetFileSize(&size2))) + { + NS_ERROR("way bad, with no happy out!"); + return 0; + } + + // by size with largest first, or by name if size is the same + int sizeDiff = int(PRInt32(nsInt64(size2) - nsInt64(size1))); + return sizeDiff != 0 ? sizeDiff : nameOrder; +} + +nsILocalFile** +xptiInterfaceInfoManager::BuildOrderedFileArray(nsISupportsArray* aSearchPath, + nsISupportsArray* aFileList, + xptiWorkingSet* aWorkingSet) +{ + // We want to end up with a file list that starts with the files from + // aWorkingSet (but only those that are in aFileList) in the order in + // which they appeared in aWorkingSet-> Following those files will be those + // files in aFileList which are not in aWorkingSet-> These additional + // files will be ordered by file size (larger first) but all .xpt files + // will preceed all zipfile of those files not already in the working set. + // To do this we will do a fancy sort on a copy of aFileList. + + nsILocalFile** orderedFileList = nsnull; + PRUint32 countOfFilesInFileList; + PRUint32 i; + + NS_ASSERTION(aFileList, "loser!"); + NS_ASSERTION(aWorkingSet, "loser!"); + NS_ASSERTION(aWorkingSet->IsValid(), "loser!"); + + if(NS_FAILED(aFileList->Count(&countOfFilesInFileList)) || + 0 == countOfFilesInFileList) + return nsnull; + + orderedFileList = (nsILocalFile**) + XPT_MALLOC(aWorkingSet->GetStructArena(), + sizeof(nsILocalFile*) * countOfFilesInFileList); + + if(!orderedFileList) + return nsnull; + + // fill our list for sorting + for(i = 0; i < countOfFilesInFileList; ++i) + { + nsCOMPtr<nsILocalFile> file; + aFileList->QueryElementAt(i, NS_GET_IID(nsILocalFile), getter_AddRefs(file)); + NS_ASSERTION(file, "loser!"); + + // Intentionally NOT addref'd cuz we know these are pinned in aFileList. + orderedFileList[i] = file.get(); + } + + // sort the filelist + + SortData sortData = {aSearchPath, aWorkingSet}; + NS_QuickSort(orderedFileList, countOfFilesInFileList, sizeof(nsILocalFile*), + xptiSortFileList, &sortData); + + return orderedFileList; +} + +xptiInterfaceInfoManager::AutoRegMode +xptiInterfaceInfoManager::DetermineAutoRegStrategy(nsISupportsArray* aSearchPath, + nsISupportsArray* aFileList, + xptiWorkingSet* aWorkingSet) +{ + NS_ASSERTION(aFileList, "loser!"); + NS_ASSERTION(aWorkingSet, "loser!"); + NS_ASSERTION(aWorkingSet->IsValid(), "loser!"); + + PRUint32 countOfFilesInWorkingSet = aWorkingSet->GetFileCount(); + PRUint32 countOfFilesInFileList; + PRUint32 i; + PRUint32 k; + + if(0 == countOfFilesInWorkingSet) + { + // Loading manifest might have failed. Better safe... + return FULL_VALIDATION_REQUIRED; + } + + if(NS_FAILED(aFileList->Count(&countOfFilesInFileList))) + { + NS_ERROR("unexpected!"); + return FULL_VALIDATION_REQUIRED; + } + + if(countOfFilesInFileList == countOfFilesInWorkingSet) + { + // try to determine if *no* files are new or changed. + + PRBool same = PR_TRUE; + for(i = 0; i < countOfFilesInFileList && same; ++i) + { + nsCOMPtr<nsILocalFile> file; + aFileList->QueryElementAt(i, NS_GET_IID(nsILocalFile), getter_AddRefs(file)); + NS_ASSERTION(file, "loser!"); + + PRInt64 size; + PRInt64 date; + nsCAutoString name; + PRUint32 directory; + + if(NS_FAILED(file->GetFileSize(&size)) || + NS_FAILED(file->GetLastModifiedTime(&date)) || + NS_FAILED(file->GetNativeLeafName(name)) || + !aWorkingSet->FindDirectoryOfFile(file, &directory)) + { + NS_ERROR("unexpected!"); + return FULL_VALIDATION_REQUIRED; + } + + for(k = 0; k < countOfFilesInWorkingSet; ++k) + { + xptiFile& target = aWorkingSet->GetFileAt(k); + + if(directory == target.GetDirectory() && + name.Equals(target.GetName())) + { + if(nsInt64(size) != target.GetSize() || + nsInt64(date) != target.GetDate()) + same = PR_FALSE; + break; + } + } + // failed to find our file in the workingset? + if(k == countOfFilesInWorkingSet) + same = PR_FALSE; + } + if(same) + return NO_FILES_CHANGED; + } + else if(countOfFilesInFileList > countOfFilesInWorkingSet) + { + // try to determine if the only changes are additional new files + // XXX Wimping out and doing this as a separate walk through the lists. + + PRBool same = PR_TRUE; + + for(i = 0; i < countOfFilesInWorkingSet && same; ++i) + { + xptiFile& target = aWorkingSet->GetFileAt(i); + + for(k = 0; k < countOfFilesInFileList; ++k) + { + nsCOMPtr<nsILocalFile> file; + aFileList->QueryElementAt(k, NS_GET_IID(nsILocalFile), getter_AddRefs(file)); + NS_ASSERTION(file, "loser!"); + + nsCAutoString name; + PRInt64 size; + PRInt64 date; + if(NS_FAILED(file->GetFileSize(&size)) || + NS_FAILED(file->GetLastModifiedTime(&date)) || + NS_FAILED(file->GetNativeLeafName(name))) + { + NS_ERROR("unexpected!"); + return FULL_VALIDATION_REQUIRED; + } + + PRBool sameName = name.Equals(target.GetName()); + if(sameName) + { + if(nsInt64(size) != target.GetSize() || + nsInt64(date) != target.GetDate()) + same = PR_FALSE; + break; + } + } + // failed to find our file in the file list? + if(k == countOfFilesInFileList) + same = PR_FALSE; + } + if(same) + return FILES_ADDED_ONLY; + } + + return FULL_VALIDATION_REQUIRED; +} + +PRBool +xptiInterfaceInfoManager::AddOnlyNewFilesFromFileList(nsISupportsArray* aSearchPath, + nsISupportsArray* aFileList, + xptiWorkingSet* aWorkingSet) +{ + nsILocalFile** orderedFileArray; + PRUint32 countOfFilesInFileList; + PRUint32 i; + + NS_ASSERTION(aFileList, "loser!"); + NS_ASSERTION(aWorkingSet, "loser!"); + NS_ASSERTION(aWorkingSet->IsValid(), "loser!"); + + if(NS_FAILED(aFileList->Count(&countOfFilesInFileList))) + return PR_FALSE; + NS_ASSERTION(countOfFilesInFileList, "loser!"); + NS_ASSERTION(countOfFilesInFileList > aWorkingSet->GetFileCount(), "loser!"); + + orderedFileArray = BuildOrderedFileArray(aSearchPath, aFileList, aWorkingSet); + + if(!orderedFileArray) + return PR_FALSE; + + // Make enough space in aWorkingset for additions to xptiFile array. + + if(!aWorkingSet->ExtendFileArray(countOfFilesInFileList)) + return PR_FALSE; + + // For each file that is not already in our working set, add any valid + // interfaces that don't conflict with previous interfaces added. + for(i = 0; i < countOfFilesInFileList; i++) + { + nsILocalFile* file = orderedFileArray[i]; + + nsCAutoString name; + PRInt64 size; + PRInt64 date; + PRUint32 dir; + if(NS_FAILED(file->GetFileSize(&size)) || + NS_FAILED(file->GetLastModifiedTime(&date)) || + NS_FAILED(file->GetNativeLeafName(name)) || + !aWorkingSet->FindDirectoryOfFile(file, &dir)) + { + return PR_FALSE; + } + + + if(xptiWorkingSet::NOT_FOUND != aWorkingSet->FindFile(dir, name.get())) + { + // This file was found in the working set, so skip it. + continue; + } + + LOG_AUTOREG((" finding interfaces in new file: %s\n", name.get())); + + xptiFile fileRecord; + fileRecord = xptiFile(nsInt64(size), nsInt64(date), dir, + name.get(), aWorkingSet); + + if(xptiFileType::IsXPT(fileRecord.GetName())) + { + XPTHeader* header = ReadXPTFile(file, aWorkingSet); + if(!header) + { + // XXX do something! + NS_ERROR(""); + continue; + } + + + xptiTypelib typelibRecord; + typelibRecord.Init(aWorkingSet->GetFileCount()); + + PRBool AddedFile = PR_FALSE; + + if(header->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) + { + NS_ASSERTION(!header->num_interfaces,"bad libxpt"); + LOG_AUTOREG((" file is version %d.%d Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION)); + } + + for(PRUint16 k = 0; k < header->num_interfaces; k++) + { + xptiInterfaceEntry* entry = nsnull; + + if(!VerifyAndAddEntryIfNew(aWorkingSet, + header->interface_directory + k, + typelibRecord, + &entry)) + return PR_FALSE; + + if(!entry) + continue; + + // If this is the first interface we found for this file then + // setup the fileRecord for the header and infos. + if(!AddedFile) + { + if(!fileRecord.SetHeader(header, aWorkingSet)) + { + // XXX that would be bad. + return PR_FALSE; + } + AddedFile = PR_TRUE; + } + fileRecord.GetGuts()->SetEntryAt(k, entry); + } + + // This will correspond to typelibRecord above. + aWorkingSet->AppendFile(fileRecord); + } + else // its another kind of archive + { + nsCOMPtr<nsIXPTLoader> loader = + do_GetService(NS_ZIPLOADER_CONTRACTID); + + if (loader) { + nsresult rv; + + nsCOMPtr<nsIXPTLoaderSink> sink = + new xptiZipLoaderSink(this, aWorkingSet); + if (!sink) + return PR_FALSE; + + rv = loader->EnumerateEntries(file, sink); + if (NS_FAILED(rv)) + return PR_FALSE; + // This will correspond to typelibRecord used in + // xptiInterfaceInfoManager::FoundEntry. + aWorkingSet->AppendFile(fileRecord); + } else { + NS_WARNING("Could not load XPT Zip loader"); + } + } + } + + return PR_TRUE; +} + +PRBool +xptiInterfaceInfoManager::DoFullValidationMergeFromFileList(nsISupportsArray* aSearchPath, + nsISupportsArray* aFileList, + xptiWorkingSet* aWorkingSet) +{ + nsILocalFile** orderedFileArray; + PRUint32 countOfFilesInFileList; + PRUint32 i; + + NS_ASSERTION(aFileList, "loser!"); + + if(!aWorkingSet->IsValid()) + return PR_FALSE; + + if(NS_FAILED(aFileList->Count(&countOfFilesInFileList))) + return PR_FALSE; + + if(!countOfFilesInFileList) + { + // maybe there are no xpt files to register. + // a minimal install would have this case. + return PR_TRUE; + } + + orderedFileArray = BuildOrderedFileArray(aSearchPath, aFileList, aWorkingSet); + + if(!orderedFileArray) + return PR_FALSE; + + // DEBUG_DumpFileArray(orderedFileArray, countOfFilesInFileList); + + // Make space in aWorkingset for a new xptiFile array. + + if(!aWorkingSet->NewFileArray(countOfFilesInFileList)) + return PR_FALSE; + + aWorkingSet->ClearZipItems(); + aWorkingSet->ClearHashTables(); + + // For each file, add any valid interfaces that don't conflict with + // previous interfaces added. + for(i = 0; i < countOfFilesInFileList; i++) + { + nsILocalFile* file = orderedFileArray[i]; + + nsCAutoString name; + PRInt64 size; + PRInt64 date; + PRUint32 dir; + if(NS_FAILED(file->GetFileSize(&size)) || + NS_FAILED(file->GetLastModifiedTime(&date)) || + NS_FAILED(file->GetNativeLeafName(name)) || + !aWorkingSet->FindDirectoryOfFile(file, &dir)) + { + return PR_FALSE; + } + + LOG_AUTOREG((" finding interfaces in file: %s\n", name.get())); + + xptiFile fileRecord; + fileRecord = xptiFile(nsInt64(size), nsInt64(date), dir, + name.get(), aWorkingSet); + +// printf("* found %s\n", fileRecord.GetName()); + + + if(xptiFileType::IsXPT(fileRecord.GetName())) + { + XPTHeader* header = ReadXPTFile(file, aWorkingSet); + if(!header) + { + // XXX do something! + NS_ERROR("Unable to read an XPT file, turn logging on to see which file"); + LOG_AUTOREG((" unable to read file\n")); + continue; + } + + xptiTypelib typelibRecord; + typelibRecord.Init(aWorkingSet->GetFileCount()); + + PRBool AddedFile = PR_FALSE; + + if(header->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) + { + NS_ASSERTION(!header->num_interfaces,"bad libxpt"); + LOG_AUTOREG((" file is version %d.%d Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION)); + } + + for(PRUint16 k = 0; k < header->num_interfaces; k++) + { + xptiInterfaceEntry* entry = nsnull; + + if(!VerifyAndAddEntryIfNew(aWorkingSet, + header->interface_directory + k, + typelibRecord, + &entry)) + return PR_FALSE; + + if(!entry) + continue; + + // If this is the first interface we found for this file then + // setup the fileRecord for the header and infos. + if(!AddedFile) + { + if(!fileRecord.SetHeader(header, aWorkingSet)) + { + // XXX that would be bad. + return PR_FALSE; + } + AddedFile = PR_TRUE; + } + fileRecord.GetGuts()->SetEntryAt(k, entry); + } + + // This will correspond to typelibRecord above. + aWorkingSet->AppendFile(fileRecord); + } + + else + { + nsCOMPtr<nsIXPTLoader> loader = + do_GetService(NS_ZIPLOADER_CONTRACTID); + + if (loader) { + nsresult rv; + + nsCOMPtr<nsIXPTLoaderSink> sink = + new xptiZipLoaderSink(this, aWorkingSet); + if (!sink) + return PR_FALSE; + + rv = loader->EnumerateEntries(file, sink); + if (NS_FAILED(rv)) + return PR_FALSE; + // This will correspond to typelibRecord used in + // xptiInterfaceInfoManager::FoundEntry. + aWorkingSet->AppendFile(fileRecord); + } else { + NS_WARNING("Could not load XPT Zip loader"); + } + } + } + return PR_TRUE; +} + +NS_IMPL_ISUPPORTS1(xptiZipLoaderSink, nsIXPTLoaderSink) + +// implement nsIXPTLoader +NS_IMETHODIMP +xptiZipLoaderSink::FoundEntry(const char* entryName, + PRInt32 index, + nsIInputStream *aStream) +{ + XPTHeader *header = + xptiZipLoader::ReadXPTFileFromInputStream(aStream, mWorkingSet); + if (!header) + return NS_ERROR_OUT_OF_MEMORY; + + if (!mManager->FoundZipEntry(entryName, index, header, mWorkingSet)) + return NS_ERROR_FAILURE; + + return NS_OK; +} + +// implement xptiEntrySink +PRBool +xptiInterfaceInfoManager::FoundZipEntry(const char* entryName, + int index, + XPTHeader* header, + xptiWorkingSet* aWorkingSet) +{ + + NS_ASSERTION(entryName, "loser!"); + NS_ASSERTION(header, "loser!"); + NS_ASSERTION(aWorkingSet, "loser!"); + + int countOfInterfacesAddedForItem = 0; + xptiZipItem zipItemRecord(entryName, aWorkingSet); + + LOG_AUTOREG((" finding interfaces in file: %s\n", entryName)); + + if(header->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) + { + NS_ASSERTION(!header->num_interfaces,"bad libxpt"); + LOG_AUTOREG((" file is version %d.%d. Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION)); + } + + if(!header->num_interfaces) + { + // We are not interested in files without interfaces. + return PR_TRUE; + } + + xptiTypelib typelibRecord; + typelibRecord.Init(aWorkingSet->GetFileCount(), + aWorkingSet->GetZipItemCount()); + + for(PRUint16 k = 0; k < header->num_interfaces; k++) + { + xptiInterfaceEntry* entry = nsnull; + + if(!VerifyAndAddEntryIfNew(aWorkingSet, + header->interface_directory + k, + typelibRecord, + &entry)) + return PR_FALSE; + + if(!entry) + continue; + + // If this is the first interface we found for this item + // then setup the zipItemRecord for the header and infos. + if(!countOfInterfacesAddedForItem) + { + // XXX fix this! + if(!zipItemRecord.SetHeader(header, aWorkingSet)) + { + // XXX that would be bad. + return PR_FALSE; + } + } + + // zipItemRecord.GetGuts()->SetEntryAt(k, entry); + ++countOfInterfacesAddedForItem; + } + + if(countOfInterfacesAddedForItem) + { + if(!aWorkingSet->GetZipItemFreeSpace()) + { + if(!aWorkingSet->ExtendZipItemArray( + aWorkingSet->GetZipItemCount() + 20)) + { + // out of space! + return PR_FALSE; + } + } + aWorkingSet->AppendZipItem(zipItemRecord); + } + return PR_TRUE; +} + +PRBool +xptiInterfaceInfoManager::VerifyAndAddEntryIfNew(xptiWorkingSet* aWorkingSet, + XPTInterfaceDirectoryEntry* iface, + const xptiTypelib& typelibRecord, + xptiInterfaceEntry** entryAdded) +{ + NS_ASSERTION(iface, "loser!"); + NS_ASSERTION(entryAdded, "loser!"); + + *entryAdded = nsnull; + + if(!iface->interface_descriptor) + { + // Not resolved, ignore this one. + // XXX full logging might note this... + return PR_TRUE; + } + + xptiHashEntry* hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aWorkingSet->mIIDTable, &iface->iid, PL_DHASH_LOOKUP); + + xptiInterfaceEntry* entry = + PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value; + + if(entry) + { + // XXX validate this info to find possible inconsistencies + LOG_AUTOREG((" ignoring repeated interface: %s\n", iface->name)); + return PR_TRUE; + } + + // Build a new xptiInterfaceEntry object and hook it up. + + entry = xptiInterfaceEntry::NewEntry(iface->name, strlen(iface->name), + iface->iid, + typelibRecord, aWorkingSet); + if(!entry) + { + // XXX bad! + return PR_FALSE; + } + + //XXX We should SetHeader too as part of the validation, no? + entry->SetScriptableFlag(XPT_ID_IS_SCRIPTABLE(iface->interface_descriptor->flags)); + + // Add our entry to the iid hashtable. + + hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aWorkingSet->mNameTable, + entry->GetTheName(), PL_DHASH_ADD); + if(hashEntry) + hashEntry->value = entry; + + // Add our entry to the name hashtable. + + hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aWorkingSet->mIIDTable, + entry->GetTheIID(), PL_DHASH_ADD); + if(hashEntry) + hashEntry->value = entry; + + *entryAdded = entry; + + LOG_AUTOREG((" added interface: %s\n", iface->name)); + + return PR_TRUE; +} + +// local struct used to pass two pointers as one pointer +struct TwoWorkingSets +{ + TwoWorkingSets(xptiWorkingSet* src, xptiWorkingSet* dest) + : aSrcWorkingSet(src), aDestWorkingSet(dest) {} + + xptiWorkingSet* aSrcWorkingSet; + xptiWorkingSet* aDestWorkingSet; +}; + +PR_STATIC_CALLBACK(PLDHashOperator) +xpti_Merger(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + xptiInterfaceEntry* srcEntry = ((xptiHashEntry*)hdr)->value; + xptiWorkingSet* aSrcWorkingSet = ((TwoWorkingSets*)arg)->aSrcWorkingSet; + xptiWorkingSet* aDestWorkingSet = ((TwoWorkingSets*)arg)->aDestWorkingSet; + + xptiHashEntry* hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aDestWorkingSet->mIIDTable, + srcEntry->GetTheIID(), PL_DHASH_LOOKUP); + + xptiInterfaceEntry* destEntry = + PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value; + + if(destEntry) + { + // Let's see if this is referring to the same exact typelib + + const char* destFilename = + aDestWorkingSet->GetTypelibFileName(destEntry->GetTypelibRecord()); + + const char* srcFilename = + aSrcWorkingSet->GetTypelibFileName(srcEntry->GetTypelibRecord()); + + if(0 == PL_strcmp(destFilename, srcFilename) && + (destEntry->GetTypelibRecord().GetZipItemIndex() == + srcEntry->GetTypelibRecord().GetZipItemIndex())) + { + // This is the same item. + // But... Let's make sure they didn't change the interface name. + // There are wacky developers that do stuff like that! + if(0 == PL_strcmp(destEntry->GetTheName(), srcEntry->GetTheName())) + return PL_DHASH_NEXT; + } + } + + // Clone the xptiInterfaceEntry into our destination WorkingSet. + + xptiTypelib typelibRecord; + + uint16 fileIndex = srcEntry->GetTypelibRecord().GetFileIndex(); + uint16 zipItemIndex = srcEntry->GetTypelibRecord().GetZipItemIndex(); + + fileIndex += aDestWorkingSet->mFileMergeOffsetMap[fileIndex]; + + // If it is not a zipItem, then the original index is fine. + if(srcEntry->GetTypelibRecord().IsZip()) + zipItemIndex += aDestWorkingSet->mZipItemMergeOffsetMap[zipItemIndex]; + + typelibRecord.Init(fileIndex, zipItemIndex); + + destEntry = xptiInterfaceEntry::NewEntry(*srcEntry, typelibRecord, + aDestWorkingSet); + if(!destEntry) + { + // XXX bad! should log + return PL_DHASH_NEXT; + } + + + // Add our entry to the iid hashtable. + + hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aDestWorkingSet->mNameTable, + destEntry->GetTheName(), PL_DHASH_ADD); + if(hashEntry) + hashEntry->value = destEntry; + + // Add our entry to the name hashtable. + + hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aDestWorkingSet->mIIDTable, + destEntry->GetTheIID(), PL_DHASH_ADD); + if(hashEntry) + hashEntry->value = destEntry; + + return PL_DHASH_NEXT; +} + +PRBool +xptiInterfaceInfoManager::MergeWorkingSets(xptiWorkingSet* aDestWorkingSet, + xptiWorkingSet* aSrcWorkingSet) +{ + + PRUint32 i; + + // Combine file lists. + + PRUint32 originalFileCount = aDestWorkingSet->GetFileCount(); + PRUint32 additionalFileCount = aSrcWorkingSet->GetFileCount(); + + // Create a new array big enough to hold both lists and copy existing files + + if(additionalFileCount) + { + if(!aDestWorkingSet->ExtendFileArray(originalFileCount + + additionalFileCount)) + return PR_FALSE; + + // Now we are where we started, but we know we have enough space. + + // Prepare offset array for later fixups. + // NOTE: Storing with dest, but alloc'ing from src. This is intentional. + aDestWorkingSet->mFileMergeOffsetMap = (PRUint32*) + XPT_CALLOC(aSrcWorkingSet->GetStructArena(), + additionalFileCount * sizeof(PRUint32)); + if(!aDestWorkingSet->mFileMergeOffsetMap) + return PR_FALSE; + } + + for(i = 0; i < additionalFileCount; ++i) + { + xptiFile& srcFile = aSrcWorkingSet->GetFileAt(i); + PRUint32 k; + for(k = 0; k < originalFileCount; ++k) + { + // If file (with same name, date, and time) is in both lists + // then reuse that record. + xptiFile& destFile = aDestWorkingSet->GetFileAt(k); + if(srcFile.Equals(destFile)) + { + aDestWorkingSet->mFileMergeOffsetMap[i] = k - i; + break; + } + } + if(k == originalFileCount) + { + // No match found, tack it on the end. + + PRUint32 newIndex = aDestWorkingSet->GetFileCount(); + + aDestWorkingSet->AppendFile(xptiFile(srcFile, aDestWorkingSet)); + + // Fixup the merge offset map. + aDestWorkingSet->mFileMergeOffsetMap[i] = newIndex - i; + } + } + + // Combine ZipItem lists. + + PRUint32 originalZipItemCount = aDestWorkingSet->GetZipItemCount(); + PRUint32 additionalZipItemCount = aSrcWorkingSet->GetZipItemCount(); + + // Create a new array big enough to hold both lists and copy existing ZipItems + + if(additionalZipItemCount) + { + if(!aDestWorkingSet->ExtendZipItemArray(originalZipItemCount + + additionalZipItemCount)) + return PR_FALSE; + + // Now we are where we started, but we know we have enough space. + + // Prepare offset array for later fixups. + // NOTE: Storing with dest, but alloc'ing from src. This is intentional. + aDestWorkingSet->mZipItemMergeOffsetMap = (PRUint32*) + XPT_CALLOC(aSrcWorkingSet->GetStructArena(), + additionalZipItemCount * sizeof(PRUint32)); + if(!aDestWorkingSet->mZipItemMergeOffsetMap) + return PR_FALSE; + } + + for(i = 0; i < additionalZipItemCount; ++i) + { + xptiZipItem& srcZipItem = aSrcWorkingSet->GetZipItemAt(i); + PRUint32 k; + for(k = 0; k < originalZipItemCount; ++k) + { + // If ZipItem (with same name) is in both lists + // then reuse that record. + xptiZipItem& destZipItem = aDestWorkingSet->GetZipItemAt(k); + if(srcZipItem.Equals(destZipItem)) + { + aDestWorkingSet->mZipItemMergeOffsetMap[i] = k - i; + break; + } + } + if(k == originalZipItemCount) + { + // No match found, tack it on the end. + + PRUint32 newIndex = aDestWorkingSet->GetZipItemCount(); + + aDestWorkingSet->AppendZipItem( + xptiZipItem(srcZipItem, aDestWorkingSet)); + + // Fixup the merge offset map. + aDestWorkingSet->mZipItemMergeOffsetMap[i] = newIndex - i; + } + } + + // Migrate xptiInterfaceInfos + + TwoWorkingSets sets(aSrcWorkingSet, aDestWorkingSet); + + PL_DHashTableEnumerate(aSrcWorkingSet->mNameTable, xpti_Merger, &sets); + + return PR_TRUE; +} + +PRBool +xptiInterfaceInfoManager::DEBUG_DumpFileList(nsISupportsArray* aFileList) +{ + PRUint32 count; + + if(NS_FAILED(aFileList->Count(&count))) + return PR_FALSE; + + for(PRUint32 i = 0; i < count; i++) + { + nsCOMPtr<nsIFile> file; + aFileList->QueryElementAt(i, NS_GET_IID(nsILocalFile), getter_AddRefs(file)); + if(!file) + return PR_FALSE; + + nsCAutoString name; + if(NS_FAILED(file->GetNativeLeafName(name))) + return PR_FALSE; + + printf("* found %s\n", name.get()); + } + return PR_TRUE; +} + +PRBool +xptiInterfaceInfoManager::DEBUG_DumpFileListInWorkingSet(xptiWorkingSet* aWorkingSet) +{ + for(PRUint16 i = 0; i < aWorkingSet->GetFileCount(); ++i) + { + xptiFile& record = aWorkingSet->GetFileAt(i); + + printf("! has %s\n", record.GetName()); + } + return PR_TRUE; +} + +PRBool +xptiInterfaceInfoManager::DEBUG_DumpFileArray(nsILocalFile** aFileArray, + PRUint32 count) +{ + // dump the sorted list + for(PRUint32 i = 0; i < count; ++i) + { + nsILocalFile* file = aFileArray[i]; + + nsCAutoString name; + if(NS_FAILED(file->GetNativeLeafName(name))) + return PR_FALSE; + + printf("found file: %s\n", name.get()); + } + return PR_TRUE; +} + +/***************************************************************************/ + +// static +void +xptiInterfaceInfoManager::WriteToLog(const char *fmt, ...) +{ + if(!gInterfaceInfoManager) + return; + + PRFileDesc* fd = gInterfaceInfoManager->GetOpenLogFile(); + if(fd) + { + va_list ap; + va_start(ap, fmt); + PR_vfprintf(fd, fmt, ap); + va_end(ap); + } +} + +PR_STATIC_CALLBACK(PLDHashOperator) +xpti_ResolvedFileNameLogger(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value; + xptiInterfaceInfoManager* mgr = (xptiInterfaceInfoManager*) arg; + + if(entry->IsFullyResolved()) + { + xptiWorkingSet* aWorkingSet = mgr->GetWorkingSet(); + PRFileDesc* fd = mgr->GetOpenLogFile(); + + const xptiTypelib& typelib = entry->GetTypelibRecord(); + const char* filename = + aWorkingSet->GetFileAt(typelib.GetFileIndex()).GetName(); + + if(typelib.IsZip()) + { + const char* zipItemName = + aWorkingSet->GetZipItemAt(typelib.GetZipItemIndex()).GetName(); + PR_fprintf(fd, "xpti used interface: %s from %s::%s\n", + entry->GetTheName(), filename, zipItemName); + } + else + { + PR_fprintf(fd, "xpti used interface: %s from %s\n", + entry->GetTheName(), filename); + } + } + return PL_DHASH_NEXT; +} + +void +xptiInterfaceInfoManager::LogStats() +{ + PRUint32 i; + + // This sets what will be returned by GetOpenLogFile(). + xptiAutoLog autoLog(this, mStatsLogFile, PR_FALSE); + + PRFileDesc* fd = GetOpenLogFile(); + if(!fd) + return; + + // Show names of xpt (only) files from which at least one interface + // was resolved. + + PRUint32 fileCount = mWorkingSet.GetFileCount(); + for(i = 0; i < fileCount; ++i) + { + xptiFile& f = mWorkingSet.GetFileAt(i); + if(f.GetGuts()) + PR_fprintf(fd, "xpti used file: %s\n", f.GetName()); + } + + PR_fprintf(fd, "\n"); + + // Show names of xptfiles loaded from zips from which at least + // one interface was resolved. + + PRUint32 zipItemCount = mWorkingSet.GetZipItemCount(); + for(i = 0; i < zipItemCount; ++i) + { + xptiZipItem& zi = mWorkingSet.GetZipItemAt(i); + if(zi.GetGuts()) + PR_fprintf(fd, "xpti used file from zip: %s\n", zi.GetName()); + } + + PR_fprintf(fd, "\n"); + + // Show name of each interface that was fully resolved and the name + // of the file and (perhaps) zip from which it was loaded. + + PL_DHashTableEnumerate(mWorkingSet.mNameTable, + xpti_ResolvedFileNameLogger, this); + +} + +/***************************************************************************/ + +// this is a private helper +static nsresult +EntryToInfo(xptiInterfaceEntry* entry, nsIInterfaceInfo **_retval) +{ + xptiInterfaceInfo* info; + nsresult rv; + + if(!entry) + { + *_retval = nsnull; + return NS_ERROR_FAILURE; + } + + rv = entry->GetInterfaceInfo(&info); + if(NS_FAILED(rv)) + return rv; + + // Transfer the AddRef done by GetInterfaceInfo. + *_retval = NS_STATIC_CAST(nsIInterfaceInfo*, info); + return NS_OK; +} + +/* nsIInterfaceInfo getInfoForIID (in nsIIDPtr iid); */ +NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForIID(const nsIID * iid, nsIInterfaceInfo **_retval) +{ + NS_ASSERTION(iid, "bad param"); + NS_ASSERTION(_retval, "bad param"); + + xptiHashEntry* hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(mWorkingSet.mIIDTable, iid, PL_DHASH_LOOKUP); + + xptiInterfaceEntry* entry = + PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value; + + return EntryToInfo(entry, _retval); +} + +/* nsIInterfaceInfo getInfoForName (in string name); */ +NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForName(const char *name, nsIInterfaceInfo **_retval) +{ + NS_ASSERTION(name, "bad param"); + NS_ASSERTION(_retval, "bad param"); + + xptiHashEntry* hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(mWorkingSet.mNameTable, name, PL_DHASH_LOOKUP); + + xptiInterfaceEntry* entry = + PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value; + + return EntryToInfo(entry, _retval); +} + +/* nsIIDPtr getIIDForName (in string name); */ +NS_IMETHODIMP xptiInterfaceInfoManager::GetIIDForName(const char *name, nsIID * *_retval) +{ + NS_ASSERTION(name, "bad param"); + NS_ASSERTION(_retval, "bad param"); + + xptiHashEntry* hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(mWorkingSet.mNameTable, name, PL_DHASH_LOOKUP); + + xptiInterfaceEntry* entry = + PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value; + + if(!entry) + { + *_retval = nsnull; + return NS_ERROR_FAILURE; + } + + return entry->GetIID(_retval); +} + +/* string getNameForIID (in nsIIDPtr iid); */ +NS_IMETHODIMP xptiInterfaceInfoManager::GetNameForIID(const nsIID * iid, char **_retval) +{ + NS_ASSERTION(iid, "bad param"); + NS_ASSERTION(_retval, "bad param"); + + xptiHashEntry* hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(mWorkingSet.mIIDTable, iid, PL_DHASH_LOOKUP); + + xptiInterfaceEntry* entry = + PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value; + + if(!entry) + { + *_retval = nsnull; + return NS_ERROR_FAILURE; + } + + return entry->GetName(_retval); +} + +PR_STATIC_CALLBACK(PLDHashOperator) +xpti_ArrayAppender(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value; + nsISupportsArray* array = (nsISupportsArray*) arg; + + nsCOMPtr<nsIInterfaceInfo> ii; + if(NS_SUCCEEDED(EntryToInfo(entry, getter_AddRefs(ii)))) + array->AppendElement(ii); + return PL_DHASH_NEXT; +} + +/* nsIEnumerator enumerateInterfaces (); */ +NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateInterfaces(nsIEnumerator **_retval) +{ + // I didn't want to incur the size overhead of using nsHashtable just to + // make building an enumerator easier. So, this code makes a snapshot of + // the table using an nsISupportsArray and builds an enumerator for that. + // We can afford this transient cost. + + nsCOMPtr<nsISupportsArray> array; + NS_NewISupportsArray(getter_AddRefs(array)); + if(!array) + return NS_ERROR_UNEXPECTED; + + PL_DHashTableEnumerate(mWorkingSet.mNameTable, xpti_ArrayAppender, array); + + return array->Enumerate(_retval); +} + +struct ArrayAndPrefix +{ + nsISupportsArray* array; + const char* prefix; + PRUint32 length; +}; + +PR_STATIC_CALLBACK(PLDHashOperator) +xpti_ArrayPrefixAppender(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value; + ArrayAndPrefix* args = (ArrayAndPrefix*) arg; + + const char* name = entry->GetTheName(); + if(name != PL_strnstr(name, args->prefix, args->length)) + return PL_DHASH_NEXT; + + nsCOMPtr<nsIInterfaceInfo> ii; + if(NS_SUCCEEDED(EntryToInfo(entry, getter_AddRefs(ii)))) + args->array->AppendElement(ii); + return PL_DHASH_NEXT; +} + +/* nsIEnumerator enumerateInterfacesWhoseNamesStartWith (in string prefix); */ +NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateInterfacesWhoseNamesStartWith(const char *prefix, nsIEnumerator **_retval) +{ + nsCOMPtr<nsISupportsArray> array; + NS_NewISupportsArray(getter_AddRefs(array)); + if(!array) + return NS_ERROR_UNEXPECTED; + + ArrayAndPrefix args = {array, prefix, PL_strlen(prefix)}; + PL_DHashTableEnumerate(mWorkingSet.mNameTable, xpti_ArrayPrefixAppender, &args); + + return array->Enumerate(_retval); +} + +/* void autoRegisterInterfaces (); */ +NS_IMETHODIMP xptiInterfaceInfoManager::AutoRegisterInterfaces() +{ + nsCOMPtr<nsISupportsArray> fileList; + AutoRegMode mode; + PRBool ok; + + nsAutoLock lock(xptiInterfaceInfoManager::GetAutoRegLock(this)); + + xptiWorkingSet workingSet(mSearchPath); + if(!workingSet.IsValid()) + return NS_ERROR_UNEXPECTED; + + // This sets what will be returned by GetOpenLogFile(). + xptiAutoLog autoLog(this, mAutoRegLogFile, PR_TRUE); + + LOG_AUTOREG(("start AutoRegister\n")); + + // We re-read the manifest rather than muck with the 'live' one. + // It is OK if this fails. + // XXX But we should track failure as a warning. + ok = xptiManifest::Read(this, &workingSet); + + LOG_AUTOREG(("read of manifest %s\n", ok ? "successful" : "FAILED")); + + // Grovel for all the typelibs we can find (in .xpt or .zip, .jar,...). + if(!BuildFileList(mSearchPath, getter_AddRefs(fileList)) || !fileList) + return NS_ERROR_UNEXPECTED; + + // DEBUG_DumpFileList(fileList); + + // Check to see how much work we need to do. + mode = DetermineAutoRegStrategy(mSearchPath, fileList, &workingSet); + + switch(mode) + { + case NO_FILES_CHANGED: + LOG_AUTOREG(("autoreg strategy: no files changed\n")); + LOG_AUTOREG(("successful end of AutoRegister\n")); + return NS_OK; + case FILES_ADDED_ONLY: + LOG_AUTOREG(("autoreg strategy: files added only\n")); + if(!AddOnlyNewFilesFromFileList(mSearchPath, fileList, &workingSet)) + { + LOG_AUTOREG(("FAILED to add new files\n")); + return NS_ERROR_UNEXPECTED; + } + break; + case FULL_VALIDATION_REQUIRED: + LOG_AUTOREG(("autoreg strategy: doing full validation merge\n")); + if(!DoFullValidationMergeFromFileList(mSearchPath, fileList, &workingSet)) + { + LOG_AUTOREG(("FAILED to do full validation\n")); + return NS_ERROR_UNEXPECTED; + } + break; + default: + NS_ERROR("switch missing a case"); + return NS_ERROR_UNEXPECTED; + } + + // Failure to write the manifest is not fatal in production builds. + // However, this would require the next startup to find and read all the + // xpt files. This will make that startup slower. If this ever becomes a + // chronic problem for anyone, then we'll want to figure out why! + + if(!xptiManifest::Write(this, &workingSet)) + { + LOG_AUTOREG(("FAILED to write manifest\n")); + NS_ERROR("Failed to write xpti manifest!"); + } + + if(!MergeWorkingSets(&mWorkingSet, &workingSet)) + { + LOG_AUTOREG(("FAILED to merge into live workingset\n")); + return NS_ERROR_UNEXPECTED; + } + +// DEBUG_DumpFileListInWorkingSet(mWorkingSet); + + LOG_AUTOREG(("successful end of AutoRegister\n")); + + return NS_OK; +} + +/***************************************************************************/ + +class xptiAdditionalManagersEnumerator : public nsISimpleEnumerator +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISIMPLEENUMERATOR + + xptiAdditionalManagersEnumerator(); + + PRBool SizeTo(PRUint32 likelyCount) {return mArray.SizeTo(likelyCount);} + PRBool AppendElement(nsIInterfaceInfoManager* element); + +private: + ~xptiAdditionalManagersEnumerator() {} + + nsSupportsArray mArray; + PRUint32 mIndex; + PRUint32 mCount; +}; + +NS_IMPL_ISUPPORTS1(xptiAdditionalManagersEnumerator, nsISimpleEnumerator) + +xptiAdditionalManagersEnumerator::xptiAdditionalManagersEnumerator() + : mIndex(0), mCount(0) +{ +} + +PRBool xptiAdditionalManagersEnumerator::AppendElement(nsIInterfaceInfoManager* element) +{ + if(!mArray.AppendElement(NS_STATIC_CAST(nsISupports*, element))) + return PR_FALSE; + mCount++; + return PR_TRUE; +} + +/* boolean hasMoreElements (); */ +NS_IMETHODIMP xptiAdditionalManagersEnumerator::HasMoreElements(PRBool *_retval) +{ + *_retval = mIndex < mCount; + return NS_OK; +} + +/* nsISupports getNext (); */ +NS_IMETHODIMP xptiAdditionalManagersEnumerator::GetNext(nsISupports **_retval) +{ + if(!(mIndex < mCount)) + { + NS_ERROR("Bad nsISimpleEnumerator caller!"); + return NS_ERROR_FAILURE; + } + + *_retval = mArray.ElementAt(mIndex++); + return *_retval ? NS_OK : NS_ERROR_FAILURE; +} + +/***************************************************************************/ + +/* void addAdditionalManager (in nsIInterfaceInfoManager manager); */ +NS_IMETHODIMP xptiInterfaceInfoManager::AddAdditionalManager(nsIInterfaceInfoManager *manager) +{ + nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(manager); + nsISupports* ptrToAdd = weakRef ? + NS_STATIC_CAST(nsISupports*, weakRef) : + NS_STATIC_CAST(nsISupports*, manager); + { // scoped lock... + nsAutoLock lock(mAdditionalManagersLock); + PRInt32 index; + nsresult rv = mAdditionalManagers.GetIndexOf(ptrToAdd, &index); + if(NS_FAILED(rv) || -1 != index) + return NS_ERROR_FAILURE; + if(!mAdditionalManagers.AppendElement(ptrToAdd)) + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +/* void removeAdditionalManager (in nsIInterfaceInfoManager manager); */ +NS_IMETHODIMP xptiInterfaceInfoManager::RemoveAdditionalManager(nsIInterfaceInfoManager *manager) +{ + nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(manager); + nsISupports* ptrToRemove = weakRef ? + NS_STATIC_CAST(nsISupports*, weakRef) : + NS_STATIC_CAST(nsISupports*, manager); + { // scoped lock... + nsAutoLock lock(mAdditionalManagersLock); + if(!mAdditionalManagers.RemoveElement(ptrToRemove)) + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +/* PRBool hasAdditionalManagers (); */ +NS_IMETHODIMP xptiInterfaceInfoManager::HasAdditionalManagers(PRBool *_retval) +{ + PRUint32 count; + nsresult rv = mAdditionalManagers.Count(&count); + *_retval = count != 0; + return rv; +} + +/* nsISimpleEnumerator enumerateAdditionalManagers (); */ +NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateAdditionalManagers(nsISimpleEnumerator **_retval) +{ + nsAutoLock lock(mAdditionalManagersLock); + + PRUint32 count; + nsresult rv = mAdditionalManagers.Count(&count); + if(NS_FAILED(rv)) + return rv; + + nsCOMPtr<xptiAdditionalManagersEnumerator> enumerator = + new xptiAdditionalManagersEnumerator(); + if(!enumerator) + return NS_ERROR_OUT_OF_MEMORY; + + enumerator->SizeTo(count); + + for(PRUint32 i = 0; i < count; /* i incremented in the loop body */) + { + nsCOMPtr<nsISupports> raw = + dont_AddRef(mAdditionalManagers.ElementAt(i++)); + if(!raw) + return NS_ERROR_FAILURE; + nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(raw); + if(weakRef) + { + nsCOMPtr<nsIInterfaceInfoManager> manager = + do_QueryReferent(weakRef); + if(manager) + { + if(!enumerator->AppendElement(manager)) + return NS_ERROR_FAILURE; + } + else + { + // The manager is no more. Remove the element. + if(!mAdditionalManagers.RemoveElementAt(--i)) + return NS_ERROR_FAILURE; + count--; + } + } + else + { + // We *know* we put a pointer to either a nsIWeakReference or + // an nsIInterfaceInfoManager into the array, so we can avoid an + // extra QI here and just do a cast. + if(!enumerator->AppendElement( + NS_REINTERPRET_CAST(nsIInterfaceInfoManager*, raw.get()))) + return NS_ERROR_FAILURE; + } + } + + NS_ADDREF(*_retval = enumerator); + return NS_OK; +} + +/***************************************************************************/ + +XPTI_PUBLIC_API(nsIInterfaceInfoManager*) +XPTI_GetInterfaceInfoManager() +{ + nsIInterfaceInfoManager* iim = + xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef(); + NS_IF_ADDREF(iim); + return iim; +} + +XPTI_PUBLIC_API(void) +XPTI_FreeInterfaceInfoManager() +{ + xptiInterfaceInfoManager::FreeInterfaceInfoManager(); +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiManifest.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiManifest.cpp new file mode 100644 index 00000000..03ab7029 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiManifest.cpp @@ -0,0 +1,710 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of xptiManifest. */ + +#include "xptiprivate.h" +#include "nsManifestLineReader.h" +#include "nsString.h" + +static const char g_Disclaimer[] = "# Generated file. ** DO NOT EDIT! **"; + +static const char g_TOKEN_Files[] = "Files"; +static const char g_TOKEN_ArchiveItems[] = "ArchiveItems"; +static const char g_TOKEN_Interfaces[] = "Interfaces"; +static const char g_TOKEN_Header[] = "Header"; +static const char g_TOKEN_Version[] = "Version"; +static const char g_TOKEN_AppDir[] = "AppDir"; +static const char g_TOKEN_Directories[] = "Directories"; + +static const int g_VERSION_MAJOR = 2; +static const int g_VERSION_MINOR = 0; + +/***************************************************************************/ + +static PRBool +GetCurrentAppDirString(xptiInterfaceInfoManager* aMgr, nsACString &aStr) +{ + nsCOMPtr<nsILocalFile> appDir; + aMgr->GetApplicationDir(getter_AddRefs(appDir)); + if(appDir) + return NS_SUCCEEDED(appDir->GetPersistentDescriptor(aStr)); + return PR_FALSE; +} + +static PRBool +CurrentAppDirMatchesPersistentDescriptor(xptiInterfaceInfoManager* aMgr, + const char *inStr) +{ + nsCOMPtr<nsILocalFile> appDir; + aMgr->GetApplicationDir(getter_AddRefs(appDir)); + + nsCOMPtr<nsILocalFile> descDir; + nsresult rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE, getter_AddRefs(descDir)); + if(NS_FAILED(rv)) + return PR_FALSE; + + rv = descDir->SetPersistentDescriptor(nsDependentCString(inStr)); + if(NS_FAILED(rv)) + return PR_FALSE; + + PRBool matches; + rv = appDir->Equals(descDir, &matches); + return NS_SUCCEEDED(rv) && matches; +} + +PR_STATIC_CALLBACK(PLDHashOperator) +xpti_InterfaceWriter(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value; + PRFileDesc* fd = (PRFileDesc*) arg; + + char* iidStr = entry->GetTheIID()->ToString(); + if(!iidStr) + return PL_DHASH_STOP; + + const xptiTypelib& typelib = entry->GetTypelibRecord(); + + PRBool success = PR_fprintf(fd, "%d,%s,%s,%d,%d,%d\n", + (int) number, + entry->GetTheName(), + iidStr, + (int) typelib.GetFileIndex(), + (int) (typelib.IsZip() ? + typelib.GetZipItemIndex() : -1), + (int) entry->GetScriptableFlag()); + + nsCRT::free(iidStr); + + return success ? PL_DHASH_NEXT : PL_DHASH_STOP; +} + + +// static +PRBool xptiManifest::Write(xptiInterfaceInfoManager* aMgr, + xptiWorkingSet* aWorkingSet) +{ + + PRBool succeeded = PR_FALSE; + PRFileDesc* fd = nsnull; + PRUint32 i; + PRUint32 size32; + PRIntn interfaceCount = 0; + nsCAutoString appDirString; + + nsCOMPtr<nsILocalFile> tempFile; + if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(tempFile)) || !tempFile) + return PR_FALSE; + + nsCAutoString originalLeafName; + tempFile->GetNativeLeafName(originalLeafName); + + nsCAutoString leafName; + leafName.Assign(originalLeafName + NS_LITERAL_CSTRING(".tmp")); + + tempFile->SetNativeLeafName(leafName); + + // All exits via "goto out;" from here on... + if(NS_FAILED(tempFile-> + OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, + 0600, &fd)) || !fd) + { + goto out; + } + + // write file header comments + + if(!PR_fprintf(fd, "%s\n", g_Disclaimer)) + goto out; + + // write the [Header] block, version number, and appdir. + + if(!PR_fprintf(fd, "\n[%s,%d]\n", g_TOKEN_Header, 2)) + goto out; + + if(!PR_fprintf(fd, "%d,%s,%d,%d\n", + 0, g_TOKEN_Version, g_VERSION_MAJOR, g_VERSION_MINOR)) + goto out; + + GetCurrentAppDirString(aMgr, appDirString); + if(appDirString.IsEmpty()) + goto out; + + if(!PR_fprintf(fd, "%d,%s,%s\n", + 1, g_TOKEN_AppDir, appDirString.get())) + goto out; + + // write Directories list + + if(!PR_fprintf(fd, "\n[%s,%d]\n", + g_TOKEN_Directories, + (int) aWorkingSet->GetDirectoryCount())) + goto out; + + for(i = 0; i < aWorkingSet->GetDirectoryCount(); i++) + { + nsCOMPtr<nsILocalFile> dir; + nsCAutoString str; + + aWorkingSet->GetDirectoryAt(i, getter_AddRefs(dir)); + if(!dir) + goto out; + + dir->GetPersistentDescriptor(str); + if(str.IsEmpty()) + goto out; + + if(!PR_fprintf(fd, "%d,%s\n", (int) i, str.get())) + goto out; + } + + // write Files list + + if(!PR_fprintf(fd, "\n[%s,%d]\n", + g_TOKEN_Files, + (int) aWorkingSet->GetFileCount())) + goto out; + + for(i = 0; i < aWorkingSet->GetFileCount(); i++) + { + const xptiFile& file = aWorkingSet->GetFileAt(i); + + LL_L2UI(size32, file.GetSize()); + + if(!PR_fprintf(fd, "%d,%s,%d,%u,%lld\n", + (int) i, + file.GetName(), + (int) file.GetDirectory(), + size32, PRInt64(file.GetDate()))) + goto out; + } + + // write ArchiveItems list + + if(!PR_fprintf(fd, "\n[%s,%d]\n", + g_TOKEN_ArchiveItems, + (int) aWorkingSet->GetZipItemCount())) + goto out; + + for(i = 0; i < aWorkingSet->GetZipItemCount(); i++) + { + if(!PR_fprintf(fd, "%d,%s\n", + (int) i, + aWorkingSet->GetZipItemAt(i).GetName())) + goto out; + } + + // write the Interfaces list + + interfaceCount = aWorkingSet->mNameTable->entryCount; + + if(!PR_fprintf(fd, "\n[%s,%d]\n", + g_TOKEN_Interfaces, + (int) interfaceCount)) + goto out; + + if(interfaceCount != (PRIntn) + PL_DHashTableEnumerate(aWorkingSet->mNameTable, + xpti_InterfaceWriter, fd)) + goto out; + + + if(PR_SUCCESS == PR_Close(fd)) + { + succeeded = PR_TRUE; + } + fd = nsnull; + +out: + if(fd) + PR_Close(fd); + + if(succeeded) + { + // delete the old file and rename this + nsCOMPtr<nsILocalFile> mainFile; + if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(mainFile)) || !mainFile) + return PR_FALSE; + + PRBool exists; + if(NS_FAILED(mainFile->Exists(&exists))) + return PR_FALSE; + + if(exists && NS_FAILED(mainFile->Remove(PR_FALSE))) + return PR_FALSE; + + nsCOMPtr<nsIFile> parent; + mainFile->GetParent(getter_AddRefs(parent)); + + // MoveTo means rename. + if(NS_FAILED(tempFile->MoveToNative(parent, originalLeafName))) + return PR_FALSE; + } + + return succeeded; +} + +/***************************************************************************/ +/***************************************************************************/ + +static char* +ReadManifestIntoMemory(xptiInterfaceInfoManager* aMgr, + PRUint32* pLength) +{ + PRFileDesc* fd = nsnull; + PRInt32 flen; + PRInt64 fileSize; + char* whole = nsnull; + PRBool success = PR_FALSE; + + nsCOMPtr<nsILocalFile> aFile; + if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(aFile)) || !aFile) + return nsnull; + +#ifdef DEBUG + { + static PRBool shown = PR_FALSE; + + nsCAutoString path; + if(!shown && NS_SUCCEEDED(aFile->GetNativePath(path)) && !path.IsEmpty()) + { + fprintf(stderr, "Type Manifest File: %s\n", path.get()); + shown = PR_TRUE; + } + } +#endif + + if(NS_FAILED(aFile->GetFileSize(&fileSize)) || !(flen = nsInt64(fileSize))) + return nsnull; + + whole = new char[flen]; + if (!whole) + return nsnull; + + // All exits from on here should be via 'goto out' + + if(NS_FAILED(aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd)) || !fd) + goto out; + + if(flen > PR_Read(fd, whole, flen)) + goto out; + + success = PR_TRUE; + + out: + if(fd) + PR_Close(fd); + + if(!success) + { + delete [] whole; + return nsnull; + } + + *pLength = flen; + return whole; +} + +static +PRBool ReadSectionHeader(nsManifestLineReader& reader, + const char *token, int minCount, int* count) +{ + while(1) + { + if(!reader.NextLine()) + break; + if(*reader.LinePtr() == '[') + { + char* p = reader.LinePtr() + (reader.LineLength() - 1); + if(*p != ']') + break; + *p = 0; + + char* values[2]; + int lengths[2]; + if(2 != reader.ParseLine(values, lengths, 2)) + break; + + // ignore the leading '[' + if(0 != PL_strcmp(values[0]+1, token)) + break; + + if((*count = atoi(values[1])) < minCount) + break; + + return PR_TRUE; + } + } + return PR_FALSE; +} + + +// static +PRBool xptiManifest::Read(xptiInterfaceInfoManager* aMgr, + xptiWorkingSet* aWorkingSet) +{ + int i; + char* whole = nsnull; + PRBool succeeded = PR_FALSE; + PRUint32 flen = 0; + nsManifestLineReader reader; + xptiHashEntry* hashEntry; + int headerCount = 0; + int dirCount = 0; + int fileCount = 0; + int zipItemCount = -1; + int interfaceCount = 0; + int dir; + int flags; + char* values[6]; // 6 is currently the max items we need to parse + int lengths[6]; + PRUint32 size32; + PRInt64 size; + PRInt64 date; + + whole = ReadManifestIntoMemory(aMgr, &flen); + if(!whole) + return PR_FALSE; + + reader.Init(whole, flen); + + // All exits from here on should be via 'goto out' + + // Look for "Header" section + + // This version accepts only version 1,0. We also freak if the header + // has more than one entry. The rationale is that we want to force an + // autoreg if the xpti.dat file was written by *any* other version of + // the software. Future versions may wish to support updating older + // manifests in some interesting way. + + if(!ReadSectionHeader(reader, g_TOKEN_Header, 2, &headerCount)) + goto out; + + if(headerCount != 2) + goto out; + + // Verify the version number + + if(!reader.NextLine()) + goto out; + + // index,VersionLiteral,major,minor + if(4 != reader.ParseLine(values, lengths, 4)) + goto out; + + // index + if(0 != atoi(values[0])) + goto out; + + // VersionLiteral + if(0 != PL_strcmp(values[1], g_TOKEN_Version)) + goto out; + + // major + if(g_VERSION_MAJOR != atoi(values[2])) + goto out; + + // minor + if(g_VERSION_MINOR != atoi(values[3])) + goto out; + + // Verify the application directory + + if(!reader.NextLine()) + goto out; + + // index,AppDirLiteral,directoryname + if(3 != reader.ParseLine(values, lengths, 3)) + goto out; + + // index + if(1 != atoi(values[0])) + goto out; + + // AppDirLiteral + if(0 != PL_strcmp(values[1], g_TOKEN_AppDir)) + goto out; + + if(!CurrentAppDirMatchesPersistentDescriptor(aMgr, values[2])) + goto out; + + // Look for "Directories" section + + if(!ReadSectionHeader(reader, g_TOKEN_Directories, 1, &dirCount)) + goto out; + else + { + // To validate that the directory list matches the current search path + // we first confirm that the list lengths match. + + nsCOMPtr<nsISupportsArray> searchPath; + aMgr->GetSearchPath(getter_AddRefs(searchPath)); + + PRUint32 searchPathCount; + searchPath->Count(&searchPathCount); + + if(dirCount != (int) searchPathCount) + goto out; + } + + // Read the directory records + + for(i = 0; i < dirCount; ++i) + { + if(!reader.NextLine()) + goto out; + + // index,directoryname + if(2 != reader.ParseLine(values, lengths, 2)) + goto out; + + // index + if(i != atoi(values[0])) + goto out; + + // directoryname + if(!aWorkingSet->DirectoryAtMatchesPersistentDescriptor(i, values[1])) + goto out; + } + + // Look for "Files" section + + if(!ReadSectionHeader(reader, g_TOKEN_Files, 1, &fileCount)) + goto out; + + + // Alloc room in the WorkingSet for the filearray. + + if(!aWorkingSet->NewFileArray(fileCount)) + goto out; + + // Read the file records + + for(i = 0; i < fileCount; ++i) + { + if(!reader.NextLine()) + goto out; + + // index,filename,dirIndex,dilesSize,filesDate + if(5 != reader.ParseLine(values, lengths, 5)) + goto out; + + // index + if(i != atoi(values[0])) + goto out; + + // filename + if(!*values[1]) + goto out; + + // dirIndex + dir = atoi(values[2]); + if(dir < 0 || dir > dirCount) + goto out; + + // fileSize + size32 = atoi(values[3]); + if(size32 <= 0) + goto out; + LL_UI2L(size, size32); + + // fileDate + date = nsCRT::atoll(values[4]); + if(LL_IS_ZERO(date)) + goto out; + + // Append a new file record to the array. + + aWorkingSet->AppendFile( + xptiFile(nsInt64(size), nsInt64(date), dir, values[1], aWorkingSet)); + } + + // Look for "ZipItems" section + + if(!ReadSectionHeader(reader, g_TOKEN_ArchiveItems, 0, &zipItemCount)) + goto out; + + // Alloc room in the WorkingSet for the zipItemarray. + + if(zipItemCount) + if(!aWorkingSet->NewZipItemArray(zipItemCount)) + goto out; + + // Read the zipItem records + + for(i = 0; i < zipItemCount; ++i) + { + if(!reader.NextLine()) + goto out; + + // index,filename + if(2 != reader.ParseLine(values, lengths, 2)) + goto out; + + // index + if(i != atoi(values[0])) + goto out; + + // filename + if(!*values[1]) + goto out; + + // Append a new zipItem record to the array. + + aWorkingSet->AppendZipItem(xptiZipItem(values[1], aWorkingSet)); + } + + // Look for "Interfaces" section + + if(!ReadSectionHeader(reader, g_TOKEN_Interfaces, 1, &interfaceCount)) + goto out; + + // Read the interface records + + for(i = 0; i < interfaceCount; ++i) + { + int fileIndex; + int zipItemIndex; + nsIID iid; + xptiInterfaceEntry* entry; + xptiTypelib typelibRecord; + + if(!reader.NextLine()) + goto out; + + // index,interfaceName,iid,fileIndex,zipIndex,flags + if(6 != reader.ParseLine(values, lengths, 6)) + goto out; + + // index + if(i != atoi(values[0])) + goto out; + + // interfaceName + if(!*values[1]) + goto out; + + // iid + if(!iid.Parse(values[2])) + goto out; + + // fileIndex + fileIndex = atoi(values[3]); + if(fileIndex < 0 || fileIndex >= fileCount) + goto out; + + // zipIndex (NOTE: -1 is a valid value) + zipItemIndex = atoi(values[4]); + if(zipItemIndex < -1 || zipItemIndex >= zipItemCount) + goto out; + + // flags + flags = atoi(values[5]); + if(flags != 0 && flags != 1) + goto out; + + // Build an InterfaceInfo and hook it in. + + if(zipItemIndex == -1) + typelibRecord.Init(fileIndex); + else + typelibRecord.Init(fileIndex, zipItemIndex); + + entry = xptiInterfaceEntry::NewEntry(values[1], lengths[1], + iid, typelibRecord, + aWorkingSet); + if(!entry) + goto out; + + entry->SetScriptableFlag(flags==1); + + // Add our entry to the iid hashtable. + + hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aWorkingSet->mNameTable, + entry->GetTheName(), PL_DHASH_ADD); + if(hashEntry) + hashEntry->value = entry; + + // Add our entry to the name hashtable. + + hashEntry = (xptiHashEntry*) + PL_DHashTableOperate(aWorkingSet->mIIDTable, + entry->GetTheIID(), PL_DHASH_ADD); + if(hashEntry) + hashEntry->value = entry; + } + + // success! + + succeeded = PR_TRUE; + + out: + if(whole) + delete [] whole; + + if(!succeeded) + { + // Cleanup the WorkingSet on failure. + aWorkingSet->InvalidateInterfaceInfos(); + aWorkingSet->ClearHashTables(); + aWorkingSet->ClearFiles(); + } + return succeeded; +} + +// static +PRBool xptiManifest::Delete(xptiInterfaceInfoManager* aMgr) +{ + nsCOMPtr<nsILocalFile> aFile; + if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(aFile)) || !aFile) + return PR_FALSE; + + PRBool exists; + if(NS_FAILED(aFile->Exists(&exists))) + return PR_FALSE; + + if(exists && NS_FAILED(aFile->Remove(PR_FALSE))) + return PR_FALSE; + + return PR_TRUE; +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiMisc.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiMisc.cpp new file mode 100644 index 00000000..a1dbf5c3 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiMisc.cpp @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of misc. xpti stuff. */ + +#include "xptiprivate.h" + +struct xptiFileTypeEntry +{ + const char* name; + int len; + xptiFileType::Type type; +}; + +static const xptiFileTypeEntry g_Entries[] = + { + {".xpt", 4, xptiFileType::XPT}, + {".zip", 4, xptiFileType::ZIP}, + {".jar", 4, xptiFileType::ZIP}, + {nsnull, 0, xptiFileType::UNKNOWN} + }; + +// static +xptiFileType::Type xptiFileType::GetType(const char* name) +{ + NS_ASSERTION(name, "loser!"); + int len = PL_strlen(name); + for(const xptiFileTypeEntry* p = g_Entries; p->name; p++) + { + if(len > p->len && 0 == PL_strcasecmp(p->name, &(name[len - p->len]))) + return p->type; + } + return UNKNOWN; +} + +/***************************************************************************/ + +MOZ_DECL_CTOR_COUNTER(xptiAutoLog) + +xptiAutoLog::xptiAutoLog(xptiInterfaceInfoManager* mgr, + nsILocalFile* logfile, PRBool append) + : mMgr(nsnull), mOldFileDesc(nsnull) +{ + MOZ_COUNT_CTOR(xptiAutoLog); + + if(mgr && logfile) + { + PRFileDesc* fd; + if(NS_SUCCEEDED(logfile-> + OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_APPEND | + (append ? 0 : PR_TRUNCATE), + 0600, &fd)) && fd) + { +#ifdef DEBUG + m_DEBUG_FileDesc = fd; +#endif + mMgr = mgr; + mOldFileDesc = mMgr->SetOpenLogFile(fd); + if(append) + PR_Seek(fd, 0, PR_SEEK_END); + WriteTimestamp(fd, "++++ start logging "); + + } + else + { +#ifdef DEBUG + printf("xpti failed to open log file for writing\n"); +#endif + } + } +} + +xptiAutoLog::~xptiAutoLog() +{ + MOZ_COUNT_DTOR(xptiAutoLog); + + if(mMgr) + { + PRFileDesc* fd = mMgr->SetOpenLogFile(mOldFileDesc); + NS_ASSERTION(fd == m_DEBUG_FileDesc, "bad unravel"); + if(fd) + { + WriteTimestamp(fd, "---- end logging "); + PR_Close(fd); + } + } +} + +void xptiAutoLog::WriteTimestamp(PRFileDesc* fd, const char* msg) +{ + PRExplodedTime expTime; + PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &expTime); + char time[128]; + PR_FormatTimeUSEnglish(time, 128, "%Y-%m-%d-%H:%M:%S", &expTime); + PR_fprintf(fd, "\n%s %s\n\n", msg, time); +} + +/***************************************************************************/ + +nsresult +xptiCloneLocalFile(nsILocalFile* aLocalFile, + nsILocalFile** aCloneLocalFile) +{ + nsresult rv; + nsCOMPtr<nsIFile> cloneRaw; + + rv = aLocalFile->Clone(getter_AddRefs(cloneRaw)); + if(NS_FAILED(rv)) + return rv; + + return CallQueryInterface(cloneRaw, aCloneLocalFile); +} + + +nsresult +xptiCloneElementAsLocalFile(nsISupportsArray* aArray, PRUint32 aIndex, + nsILocalFile** aLocalFile) +{ + nsresult rv; + nsCOMPtr<nsILocalFile> original; + + rv = aArray->QueryElementAt(aIndex, NS_GET_IID(nsILocalFile), + getter_AddRefs(original)); + if(NS_FAILED(rv)) + return rv; + + return xptiCloneLocalFile(original, aLocalFile); +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp new file mode 100644 index 00000000..50956585 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of xptiTypelibGuts. */ + +#include "xptiprivate.h" + +// static +xptiTypelibGuts* +xptiTypelibGuts::NewGuts(XPTHeader* aHeader, + xptiWorkingSet* aWorkingSet) +{ + NS_ASSERTION(aHeader, "bad param"); + void* place = XPT_MALLOC(aWorkingSet->GetStructArena(), + sizeof(xptiTypelibGuts) + + (sizeof(xptiInterfaceEntry*) * + (aHeader->num_interfaces - 1))); + if(!place) + return nsnull; + return new(place) xptiTypelibGuts(aHeader); +} + +xptiTypelibGuts::xptiTypelibGuts(XPTHeader* aHeader) + : mHeader(aHeader) +{ + // empty +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp new file mode 100644 index 00000000..b9602726 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp @@ -0,0 +1,432 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of xptiWorkingSet. */ + +#include "xptiprivate.h" +#include "nsString.h" + +#define XPTI_STRING_ARENA_BLOCK_SIZE (1024 * 1) +#define XPTI_STRUCT_ARENA_BLOCK_SIZE (1024 * 1) +#define XPTI_HASHTABLE_SIZE 128 + +/***************************************************************************/ + +PR_STATIC_CALLBACK(const void*) +IIDGetKey(PLDHashTable *table, PLDHashEntryHdr *entry) +{ + return ((xptiHashEntry*)entry)->value->GetTheIID(); +} + +PR_STATIC_CALLBACK(PLDHashNumber) +IIDHash(PLDHashTable *table, const void *key) +{ + return (PLDHashNumber) ((const nsIID*)key)->m0; +} + +PR_STATIC_CALLBACK(PRBool) +IIDMatch(PLDHashTable *table, + const PLDHashEntryHdr *entry, + const void *key) +{ + const nsIID* iid1 = ((xptiHashEntry*)entry)->value->GetTheIID(); + const nsIID* iid2 = (const nsIID*)key; + + return iid1 == iid2 || iid1->Equals(*iid2); +} + +const static struct PLDHashTableOps IIDTableOps = +{ + PL_DHashAllocTable, + PL_DHashFreeTable, + IIDGetKey, + IIDHash, + IIDMatch, + PL_DHashMoveEntryStub, + PL_DHashClearEntryStub, + PL_DHashFinalizeStub +}; + +/***************************************************************************/ + +PR_STATIC_CALLBACK(const void*) +NameGetKey(PLDHashTable *table, PLDHashEntryHdr *entry) +{ + return ((xptiHashEntry*)entry)->value->GetTheName(); +} + +PR_STATIC_CALLBACK(PRBool) +NameMatch(PLDHashTable *table, + const PLDHashEntryHdr *entry, + const void *key) +{ + const char* str1 = ((xptiHashEntry*)entry)->value->GetTheName(); + const char* str2 = (const char*) key; + return str1 == str2 || 0 == PL_strcmp(str1, str2); +} + +static const struct PLDHashTableOps NameTableOps = +{ + PL_DHashAllocTable, + PL_DHashFreeTable, + NameGetKey, + PL_DHashStringKey, + NameMatch, + PL_DHashMoveEntryStub, + PL_DHashClearEntryStub, + PL_DHashFinalizeStub +}; + +/***************************************************************************/ + +MOZ_DECL_CTOR_COUNTER(xptiWorkingSet) + +xptiWorkingSet::xptiWorkingSet(nsISupportsArray* aDirectories) + : mFileCount(0), + mMaxFileCount(0), + mFileArray(nsnull), + mZipItemCount(0), + mMaxZipItemCount(0), + mZipItemArray(nsnull), + mStringArena(XPT_NewArena(XPTI_STRING_ARENA_BLOCK_SIZE, sizeof(char), + "xptiWorkingSet strings")), + mStructArena(XPT_NewArena(XPTI_STRUCT_ARENA_BLOCK_SIZE, sizeof(double), + "xptiWorkingSet structs")), + mDirectories(aDirectories), + mNameTable(PL_NewDHashTable(&NameTableOps, nsnull, sizeof(xptiHashEntry), + XPTI_HASHTABLE_SIZE)), + mIIDTable(PL_NewDHashTable(&IIDTableOps, nsnull, sizeof(xptiHashEntry), + XPTI_HASHTABLE_SIZE)), + mFileMergeOffsetMap(nsnull), + mZipItemMergeOffsetMap(nsnull) +{ + MOZ_COUNT_CTOR(xptiWorkingSet); + // do nothing else... +} + +PRBool +xptiWorkingSet::IsValid() const +{ + return (mFileCount == 0 || mFileArray) && + (mZipItemCount == 0 || mZipItemArray) && + mStringArena && + mStructArena && + mNameTable && + mIIDTable; +} + +PR_STATIC_CALLBACK(PLDHashOperator) +xpti_Remover(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + return PL_DHASH_REMOVE; +} + +PR_STATIC_CALLBACK(PLDHashOperator) +xpti_Invalidator(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value; + entry->LockedInvalidateInterfaceInfo(); + return PL_DHASH_NEXT; +} + +void +xptiWorkingSet::InvalidateInterfaceInfos() +{ + if(mNameTable) + { + nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor()); + PL_DHashTableEnumerate(mNameTable, xpti_Invalidator, nsnull); + } +} + +void +xptiWorkingSet::ClearHashTables() +{ + if(mNameTable) + PL_DHashTableEnumerate(mNameTable, xpti_Remover, nsnull); + + if(mIIDTable) + PL_DHashTableEnumerate(mIIDTable, xpti_Remover, nsnull); +} + +void +xptiWorkingSet::ClearFiles() +{ + if(mFileArray) + delete [] mFileArray; + mFileArray = nsnull; + mMaxFileCount = 0; + mFileCount = 0; +} + +void +xptiWorkingSet::ClearZipItems() +{ + if(mZipItemArray) + delete [] mZipItemArray; + mZipItemArray = nsnull; + mMaxZipItemCount = 0; + mZipItemCount = 0; +} + +xptiWorkingSet::~xptiWorkingSet() +{ + MOZ_COUNT_DTOR(xptiWorkingSet); + + ClearFiles(); + ClearZipItems(); + ClearHashTables(); + + if(mNameTable) + PL_DHashTableDestroy(mNameTable); + + if(mIIDTable) + PL_DHashTableDestroy(mIIDTable); + + if(mFileArray) + delete [] mFileArray; + + if(mZipItemArray) + delete [] mZipItemArray; + + // Destroy arenas last in case they are referenced in other members' dtors. + + if(mStringArena) + { +#ifdef DEBUG + XPT_DumpStats(mStringArena); +#endif + XPT_DestroyArena(mStringArena); + } + + if(mStructArena) + { +#ifdef DEBUG + XPT_DumpStats(mStructArena); +#endif + XPT_DestroyArena(mStructArena); + } +} + +PRUint32 +xptiWorkingSet::FindFile(PRUint32 dir, const char* name) +{ + if(mFileArray) + { + for(PRUint32 i = 0; i < mFileCount;++i) + { + xptiFile& file = mFileArray[i]; + if(file.GetDirectory() == dir && + 0 == PL_strcmp(name, file.GetName())) + { + return i; + } + } + } + return NOT_FOUND; +} + +PRBool +xptiWorkingSet::NewFileArray(PRUint32 count) +{ + if(mFileArray) + delete [] mFileArray; + mFileCount = 0; + mFileArray = new xptiFile[count]; + if(!mFileArray) + { + mMaxFileCount = 0; + return PR_FALSE; + } + mMaxFileCount = count; + return PR_TRUE; +} + +PRBool +xptiWorkingSet::ExtendFileArray(PRUint32 count) +{ + if(mFileArray && count < mMaxFileCount) + return PR_TRUE; + + xptiFile* newArray = new xptiFile[count]; + if(!newArray) + return PR_FALSE; + + if(mFileArray) + { + for(PRUint32 i = 0; i < mFileCount; ++i) + newArray[i] = mFileArray[i]; + delete [] mFileArray; + } + mFileArray = newArray; + mMaxFileCount = count; + return PR_TRUE; +} + +/***************************************************************************/ + +PRUint32 +xptiWorkingSet::FindZipItemWithName(const char* name) +{ + if(mZipItemArray) + { + for(PRUint32 i = 0; i < mZipItemCount;++i) + if(0 == PL_strcmp(name, mZipItemArray[i].GetName())) + return i; + } + return NOT_FOUND; +} + +PRBool +xptiWorkingSet::NewZipItemArray(PRUint32 count) +{ + if(mZipItemArray) + delete [] mZipItemArray; + mZipItemCount = 0; + mZipItemArray = new xptiZipItem[count]; + if(!mZipItemArray) + { + mMaxZipItemCount = 0; + return PR_FALSE; + } + mMaxZipItemCount = count; + return PR_TRUE; +} + +PRBool +xptiWorkingSet::ExtendZipItemArray(PRUint32 count) +{ + if(mZipItemArray && count < mMaxZipItemCount) + return PR_TRUE; + + xptiZipItem* newArray = new xptiZipItem[count]; + if(!newArray) + return PR_FALSE; + + if(mZipItemArray) + { + for(PRUint32 i = 0; i < mZipItemCount; ++i) + newArray[i] = mZipItemArray[i]; + delete [] mZipItemArray; + } + mZipItemArray = newArray; + mMaxZipItemCount = count; + return PR_TRUE; +} + +/***************************************************************************/ +// Directory stuff... + +PRUint32 xptiWorkingSet::GetDirectoryCount() +{ + PRUint32 count = 0; + mDirectories->Count(&count); + return count; +} + +nsresult xptiWorkingSet::GetCloneOfDirectoryAt(PRUint32 i, nsILocalFile** dir) +{ + return xptiCloneElementAsLocalFile(mDirectories, i, dir); +} + +nsresult xptiWorkingSet::GetDirectoryAt(PRUint32 i, nsILocalFile** dir) +{ + return mDirectories->QueryElementAt(i, NS_GET_IID(nsILocalFile), (void**)dir); +} + +PRBool xptiWorkingSet::FindDirectory(nsILocalFile* dir, PRUint32* index) +{ + PRUint32 count; + nsresult rv = mDirectories->Count(&count); + if(NS_FAILED(rv)) + return PR_FALSE; + + for(PRUint32 i = 0; i < count; i++) + { + PRBool same; + nsCOMPtr<nsILocalFile> current; + mDirectories->QueryElementAt(i, NS_GET_IID(nsILocalFile), + getter_AddRefs(current)); + if(!current || NS_FAILED(current->Equals(dir, &same))) + break; + if(same) + { + *index = i; + return PR_TRUE; + } + } + return PR_FALSE; +} + +PRBool xptiWorkingSet::FindDirectoryOfFile(nsILocalFile* file, PRUint32* index) +{ + nsCOMPtr<nsIFile> dirAbstract; + file->GetParent(getter_AddRefs(dirAbstract)); + if(!dirAbstract) + return PR_FALSE; + nsCOMPtr<nsILocalFile> dir = do_QueryInterface(dirAbstract); + if(!dir) + return PR_FALSE; + return FindDirectory(dir, index); +} + +PRBool xptiWorkingSet::DirectoryAtMatchesPersistentDescriptor(PRUint32 i, + const char* inDesc) +{ + nsCOMPtr<nsILocalFile> dir; + GetDirectoryAt(i, getter_AddRefs(dir)); + if(!dir) + return PR_FALSE; + + nsCOMPtr<nsILocalFile> descDir; + nsresult rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE, getter_AddRefs(descDir)); + if(NS_FAILED(rv)) + return PR_FALSE; + + rv = descDir->SetPersistentDescriptor(nsDependentCString(inDesc)); + if(NS_FAILED(rv)) + return PR_FALSE; + + PRBool matches; + rv = dir->Equals(descDir, &matches); + return NS_SUCCEEDED(rv) && matches; +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiZipItem.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiZipItem.cpp new file mode 100644 index 00000000..c9a6178b --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiZipItem.cpp @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of xptiZipItem. */ + +#include "xptiprivate.h" + +MOZ_DECL_CTOR_COUNTER(xptiZipItem) + +xptiZipItem::xptiZipItem() + : +#ifdef DEBUG + mDEBUG_WorkingSet(nsnull), +#endif + mName(nsnull), + mGuts(nsnull) +{ + MOZ_COUNT_CTOR(xptiZipItem); + // empty +} + +xptiZipItem::xptiZipItem(const char* aName, + xptiWorkingSet* aWorkingSet) + + : +#ifdef DEBUG + mDEBUG_WorkingSet(aWorkingSet), +#endif + mName(aName), + mGuts(nsnull) +{ + MOZ_COUNT_CTOR(xptiZipItem); + + NS_ASSERTION(aWorkingSet,"bad param"); + mName = XPT_STRDUP(aWorkingSet->GetStringArena(), aName); +} + +xptiZipItem::xptiZipItem(const xptiZipItem& r, xptiWorkingSet* aWorkingSet) + : +#ifdef DEBUG + mDEBUG_WorkingSet(aWorkingSet), +#endif + mName(nsnull), + mGuts(nsnull) +{ + MOZ_COUNT_CTOR(xptiZipItem); + + NS_ASSERTION(aWorkingSet,"bad param"); + mName = XPT_STRDUP(aWorkingSet->GetStringArena(), r.mName); +} + +xptiZipItem::~xptiZipItem() +{ + MOZ_COUNT_DTOR(xptiZipItem); +} + +PRBool +xptiZipItem::SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet) +{ + NS_ASSERTION(!mGuts,"bad state"); + NS_ASSERTION(aHeader,"bad param"); + NS_ASSERTION(aWorkingSet,"bad param"); + + mGuts = xptiTypelibGuts::NewGuts(aHeader, aWorkingSet); + return mGuts != nsnull; +} diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiZipLoader.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiZipLoader.cpp new file mode 100644 index 00000000..caba49d5 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiZipLoader.cpp @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of xptiZipLoader. */ + +#include "xptiprivate.h" + +XPTHeader* +xptiZipLoader::ReadXPTFileFromInputStream(nsIInputStream *stream, + xptiWorkingSet* aWorkingSet) +{ + XPTCursor cursor; + PRUint32 totalRead = 0; + XPTState *state = nsnull; + XPTHeader *header = nsnull; + + PRUint32 flen; + stream->Available(&flen); + + char *whole = new char[flen]; + if (!whole) + { + return nsnull; + } + + // all exits from on here should be via 'goto out' + + while(flen - totalRead) + { + PRUint32 avail; + PRUint32 read; + + if(NS_FAILED(stream->Available(&avail))) + { + goto out; + } + + if(avail > flen) + { + goto out; + } + + if(NS_FAILED(stream->Read(whole+totalRead, avail, &read))) + { + goto out; + } + + totalRead += read; + } + + // Go ahead and close the stream now. + stream = nsnull; + + if(!(state = XPT_NewXDRState(XPT_DECODE, whole, flen))) + { + goto out; + } + + if(!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor)) + { + goto out; + } + + if (!XPT_DoHeader(aWorkingSet->GetStructArena(), &cursor, &header)) + { + header = nsnull; + goto out; + } + + out: + if(state) + XPT_DestroyXDRState(state); + if(whole) + delete [] whole; + return header; +} + diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiprivate.h b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiprivate.h new file mode 100644 index 00000000..3d159c2c --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiprivate.h @@ -0,0 +1,981 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Library-private header for Interface Info system. */ + +#ifndef xptiprivate_h___ +#define xptiprivate_h___ + +#include "nscore.h" +#include "nsISupports.h" + +// this after nsISupports, to pick up IID +// so that xpt stuff doesn't try to define it itself... +#include "xpt_struct.h" +#include "xpt_xdr.h" + +#include "nsIInterfaceInfo.h" +#include "nsIInterfaceInfoManager.h" +#include "xptinfo.h" +#include "nsIXPTLoader.h" + +#include "nsIServiceManager.h" +#include "nsILocalFile.h" +#include "nsIDirectoryService.h" +#include "nsDirectoryServiceDefs.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsIWeakReference.h" + +#include "nsCRT.h" +#include "nsMemory.h" + +#include "nsISupportsArray.h" +#include "nsSupportsArray.h" +#include "nsInt64.h" + +#include "nsQuickSort.h" + +#include "nsXPIDLString.h" + +#include "nsIInputStream.h" + +#include "nsAutoLock.h" + +#include "pldhash.h" +#include "plstr.h" +#include "prprf.h" +#include "prio.h" +#include "prtime.h" +#include "prenv.h" + +#include <stdio.h> +#include <stdarg.h> + +/***************************************************************************/ + +#if 0 && defined(DEBUG_jband) +#define LOG_RESOLVE(x) printf x +#define LOG_LOAD(x) printf x +#define LOG_AUTOREG(x) do{printf x; xptiInterfaceInfoManager::WriteToLog x;}while(0) +#else +#define LOG_RESOLVE(x) ((void)0) +#define LOG_LOAD(x) ((void)0) +#define LOG_AUTOREG(x) xptiInterfaceInfoManager::WriteToLog x +#endif + +#if 1 && defined(DEBUG_jband) +#define SHOW_INFO_COUNT_STATS +#endif + +/***************************************************************************/ + +class xptiFile; +class xptiInterfaceInfo; +class xptiInterfaceInfoManager; +class xptiInterfaceEntry; +class xptiInterfaceGuts; +class xptiTypelibGuts; +class xptiWorkingSet; + +/***************************************************************************/ + +class xptiTypelib +{ +public: + // No ctors or dtors so that we can be in a union in xptiInterfaceInfo. + // Allow automatic shallow copies. + + uint16 GetFileIndex() const {return mFileIndex;} + uint16 GetZipItemIndex() const {return mZipItemIndex;} + + enum {NOT_ZIP = 0xffff}; + + PRBool IsZip() const {return mZipItemIndex != NOT_ZIP;} + + void Init(uint16 aFileIndex, uint16 aZipItemIndex = NOT_ZIP) + {mFileIndex = aFileIndex; mZipItemIndex = aZipItemIndex;} + + PRBool Equals(const xptiTypelib& r) const + {return mFileIndex == r.mFileIndex && + mZipItemIndex == r.mZipItemIndex;} + +private: + uint16 mFileIndex; + uint16 mZipItemIndex; +}; + +/***************************************************************************/ + +// No virtuals. +// These are always constructed in the struct arena using placement new. +// dtor need not be called. + +class xptiTypelibGuts +{ +public: + static xptiTypelibGuts* NewGuts(XPTHeader* aHeader, + xptiWorkingSet* aWorkingSet); + + XPTHeader* GetHeader() {return mHeader;} + PRUint16 GetEntryCount() const {return mHeader->num_interfaces;} + + void SetEntryAt(PRUint16 i, xptiInterfaceEntry* ptr) + { + NS_ASSERTION(mHeader,"bad state!"); + NS_ASSERTION(i < GetEntryCount(),"bad param!"); + mEntryArray[i] = ptr; + } + + xptiInterfaceEntry* GetEntryAt(PRUint16 i) const + { + NS_ASSERTION(mHeader,"bad state!"); + NS_ASSERTION(i < GetEntryCount(),"bad param!"); + return mEntryArray[i]; + } + +private: + xptiTypelibGuts(); // not implemented + xptiTypelibGuts(XPTHeader* aHeader); + ~xptiTypelibGuts() {} + void* operator new(size_t, void* p) CPP_THROW_NEW {return p;} + +private: + XPTHeader* mHeader; // hold pointer into arena + xptiInterfaceEntry* mEntryArray[1]; // Always last. Sized to fit. +}; + +/***************************************************************************/ + +class xptiFile +{ +public: + const nsInt64& GetSize() const {return mSize;} + const nsInt64& GetDate() const {return mDate;} + const char* GetName() const {return mName;} + /*const*/ PRUint32 GetDirectory() const {return mDirectory;} + xptiTypelibGuts* GetGuts() {return mGuts;} + + xptiFile(); + + xptiFile(const nsInt64& aSize, + const nsInt64& aDate, + PRUint32 aDirectory, + const char* aName, + xptiWorkingSet* aWorkingSet); + + xptiFile(const xptiFile& r, xptiWorkingSet* aWorkingSet); + + ~xptiFile(); + + PRBool SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet); + + PRBool Equals(const xptiFile& r) const + { + return mDirectory == r.mDirectory && + mSize == r.mSize && + mDate == r.mDate && + 0 == PL_strcmp(mName, r.mName); + } + + xptiFile(const xptiFile& r) {CopyFields(r);} + xptiFile& operator= (const xptiFile& r) + { + if(this != &r) + CopyFields(r); + return *this; + } + +private: + void CopyFields(const xptiFile& r) + { +#ifdef DEBUG + // If 'this' has a workingset then it better match that of the assigner. + NS_ASSERTION(!mDEBUG_WorkingSet || + mDEBUG_WorkingSet == r.mDEBUG_WorkingSet, + "illegal xptiFile assignment"); + mDEBUG_WorkingSet = r.mDEBUG_WorkingSet; +#endif + + mSize = r.mSize; + mDate = r.mDate; + mName = r.mName; + mDirectory = r.mDirectory; + mGuts = r.mGuts; + } + +private: +#ifdef DEBUG + xptiWorkingSet* mDEBUG_WorkingSet; +#endif + nsInt64 mSize; + nsInt64 mDate; + const char* mName; // hold pointer into arena from initializer + xptiTypelibGuts* mGuts; // hold pointer into arena + PRUint32 mDirectory; +}; + +/***************************************************************************/ + +class xptiZipItem +{ +public: + const char* GetName() const {return mName;} + xptiTypelibGuts* GetGuts() {return mGuts;} + + xptiZipItem(); + + xptiZipItem(const char* aName, + xptiWorkingSet* aWorkingSet); + + xptiZipItem(const xptiZipItem& r, xptiWorkingSet* aWorkingSet); + + ~xptiZipItem(); + + PRBool SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet); + + PRBool Equals(const xptiZipItem& r) const + { + return 0 == PL_strcmp(mName, r.mName); + } + + xptiZipItem(const xptiZipItem& r) {CopyFields(r);} + xptiZipItem& operator= (const xptiZipItem& r) + { + if(this != &r) + CopyFields(r); + return *this; + } + +private: + void CopyFields(const xptiZipItem& r) + { +#ifdef DEBUG + // If 'this' has a workingset then it better match that of the assigner. + NS_ASSERTION(!mDEBUG_WorkingSet || + mDEBUG_WorkingSet == r.mDEBUG_WorkingSet, + "illegal xptiFile assignment"); + mDEBUG_WorkingSet = r.mDEBUG_WorkingSet; +#endif + + mName = r.mName; + mGuts = r.mGuts; + } + +private: +#ifdef DEBUG + xptiWorkingSet* mDEBUG_WorkingSet; +#endif + const char* mName; // hold pointer into arena from initializer + xptiTypelibGuts* mGuts; // hold pointer into arena +}; + +/***************************************************************************/ + +class xptiWorkingSet +{ +public: + xptiWorkingSet(); // not implmented + xptiWorkingSet(nsISupportsArray* aDirectories); + ~xptiWorkingSet(); + + PRBool IsValid() const; + + void InvalidateInterfaceInfos(); + void ClearHashTables(); + void ClearFiles(); + void ClearZipItems(); + + // utility methods... + + xptiTypelibGuts* GetTypelibGuts(const xptiTypelib& typelib) + { + return typelib.IsZip() ? + GetZipItemAt(typelib.GetZipItemIndex()).GetGuts() : + GetFileAt(typelib.GetFileIndex()).GetGuts(); + } + + enum {NOT_FOUND = 0xffffffff}; + + // FileArray stuff... + + PRUint32 GetFileCount() const {return mFileCount;} + PRUint32 GetFileFreeSpace() + {return mFileArray ? mMaxFileCount - mFileCount : 0;} + + PRUint32 FindFile(PRUint32 dir, const char* name); + + PRUint32 GetTypelibDirectoryIndex(const xptiTypelib& typelib) + { + return GetFileAt(typelib.GetFileIndex()).GetDirectory(); + } + + const char* GetTypelibFileName(const xptiTypelib& typelib) + { + return GetFileAt(typelib.GetFileIndex()).GetName(); + } + + xptiFile& GetFileAt(PRUint32 i) const + { + NS_ASSERTION(mFileArray, "bad state!"); + NS_ASSERTION(i < mFileCount, "bad param!"); + return mFileArray[i]; + } + + void SetFileAt(PRUint32 i, const xptiFile& r) + { + NS_ASSERTION(mFileArray, "bad state!"); + NS_ASSERTION(i < mFileCount, "bad param!"); + mFileArray[i] = r; + } + + void AppendFile(const xptiFile& r) + { + NS_ASSERTION(mFileArray, "bad state!"); + NS_ASSERTION(mFileCount < mMaxFileCount, "bad param!"); + mFileArray[mFileCount++] = r; + } + + PRBool NewFileArray(PRUint32 count); + PRBool ExtendFileArray(PRUint32 count); + + // ZipItemArray stuff... + + PRUint32 GetZipItemCount() const {return mZipItemCount;} + PRUint32 GetZipItemFreeSpace() + {return mZipItemArray ? mMaxZipItemCount - mZipItemCount : 0;} + + PRUint32 FindZipItemWithName(const char* name); + + xptiZipItem& GetZipItemAt(PRUint32 i) const + { + NS_ASSERTION(mZipItemArray, "bad state!"); + NS_ASSERTION(i < mZipItemCount, "bad param!"); + return mZipItemArray[i]; + } + + void SetZipItemAt(PRUint32 i, const xptiZipItem& r) + { + NS_ASSERTION(mZipItemArray, "bad state!"); + NS_ASSERTION(i < mZipItemCount, "bad param!"); + mZipItemArray[i] = r; + } + + void AppendZipItem(const xptiZipItem& r) + { + NS_ASSERTION(mZipItemArray, "bad state!"); + NS_ASSERTION(mZipItemCount < mMaxZipItemCount, "bad param!"); + mZipItemArray[mZipItemCount++] = r; + } + + PRBool NewZipItemArray(PRUint32 count); + PRBool ExtendZipItemArray(PRUint32 count); + + // Directory stuff... + + PRUint32 GetDirectoryCount(); + nsresult GetCloneOfDirectoryAt(PRUint32 i, nsILocalFile** dir); + nsresult GetDirectoryAt(PRUint32 i, nsILocalFile** dir); + PRBool FindDirectory(nsILocalFile* dir, PRUint32* index); + PRBool FindDirectoryOfFile(nsILocalFile* file, PRUint32* index); + PRBool DirectoryAtMatchesPersistentDescriptor(PRUint32 i, const char* desc); + + // Arena stuff... + + XPTArena* GetStringArena() {return mStringArena;} + XPTArena* GetStructArena() {return mStructArena;} + + +private: + PRUint32 mFileCount; + PRUint32 mMaxFileCount; + xptiFile* mFileArray; // using new[] and delete[] + + PRUint32 mZipItemCount; + PRUint32 mMaxZipItemCount; + xptiZipItem* mZipItemArray; // using new[] and delete[] + + XPTArena* mStringArena; + XPTArena* mStructArena; + + nsCOMPtr<nsISupportsArray> mDirectories; + +public: + // XXX make these private with accessors + PLDHashTable* mNameTable; + PLDHashTable* mIIDTable; + PRUint32* mFileMergeOffsetMap; // always in an arena + PRUint32* mZipItemMergeOffsetMap; // always in an arena +}; + +/***************************************************************************/ + +class xptiInterfaceGuts +{ +public: + uint16 mMethodBaseIndex; + uint16 mConstantBaseIndex; + xptiInterfaceEntry* mParent; + XPTInterfaceDescriptor* mDescriptor; + xptiTypelib mTypelib; + xptiWorkingSet* mWorkingSet; + + static xptiInterfaceGuts* NewGuts(XPTInterfaceDescriptor* aDescriptor, + const xptiTypelib& aTypelib, + xptiWorkingSet* aWorkingSet) + { + void* place = XPT_MALLOC(aWorkingSet->GetStructArena(), + sizeof(xptiInterfaceGuts)); + if(!place) + return nsnull; + return new(place) xptiInterfaceGuts(aDescriptor, aTypelib, aWorkingSet); + } + +private: + void* operator new(size_t, void* p) CPP_THROW_NEW {return p;} + xptiInterfaceGuts(XPTInterfaceDescriptor* aDescriptor, + const xptiTypelib& aTypelib, + xptiWorkingSet* aWorkingSet) + : mMethodBaseIndex(0), + mConstantBaseIndex(0), + mParent(nsnull), + mDescriptor(aDescriptor), + mTypelib(aTypelib), + mWorkingSet(aWorkingSet) {} + + ~xptiInterfaceGuts() {} +}; + +/***************************************************************************/ + +// This class exists to help xptiInterfaceInfo store a 4-state (2 bit) value +// and a set of bitflags in one 8bit value. See below. + +class xptiInfoFlags +{ + enum {STATE_MASK = 3}; +public: + xptiInfoFlags(uint8 n) : mData(n) {} + xptiInfoFlags(const xptiInfoFlags& r) : mData(r.mData) {} + + static uint8 GetStateMask() + {return uint8(STATE_MASK);} + + void Clear() + {mData = 0;} + + uint8 GetData() const + {return mData;} + + uint8 GetState() const + {return mData & GetStateMask();} + + void SetState(uint8 state) + {mData &= ~GetStateMask(); mData |= state;} + + void SetFlagBit(uint8 flag, PRBool on) + {if(on) + mData |= ~GetStateMask() & flag; + else + mData &= GetStateMask() | ~flag;} + + PRBool GetFlagBit(uint8 flag) const + {return (mData & flag) ? PR_TRUE : PR_FALSE;} + +private: + uint8 mData; +}; + +/****************************************************/ + +// No virtual methods. +// We always create in the struct arena and construct using "placement new". +// No members need dtor calls. + +class xptiInterfaceEntry +{ +public: + static xptiInterfaceEntry* NewEntry(const char* name, + int nameLength, + const nsID& iid, + const xptiTypelib& typelib, + xptiWorkingSet* aWorkingSet); + + static xptiInterfaceEntry* NewEntry(const xptiInterfaceEntry& r, + const xptiTypelib& typelib, + xptiWorkingSet* aWorkingSet); + + enum { + NOT_RESOLVED = 0, + PARTIALLY_RESOLVED = 1, + FULLY_RESOLVED = 2, + RESOLVE_FAILED = 3 + }; + + // Additional bit flags... + enum {SCRIPTABLE = 4}; + + uint8 GetResolveState() const {return mFlags.GetState();} + + PRBool IsFullyResolved() const + {return GetResolveState() == (uint8) FULLY_RESOLVED;} + + PRBool HasInterfaceRecord() const + {int s = (int) GetResolveState(); + return (s == PARTIALLY_RESOLVED || s == FULLY_RESOLVED) && mInterface;} + + const xptiTypelib& GetTypelibRecord() const + {return HasInterfaceRecord() ? mInterface->mTypelib : mTypelib;} + + xptiInterfaceGuts* GetInterfaceGuts() const + {return HasInterfaceRecord() ? mInterface : nsnull;} + +#ifdef DEBUG + PRBool DEBUG_ScriptableFlagIsValid() const + {int s = (int) GetResolveState(); + if((s == PARTIALLY_RESOLVED || s == FULLY_RESOLVED) && mInterface) + { + if(XPT_ID_IS_SCRIPTABLE(mInterface->mDescriptor->flags)) + return GetScriptableFlag(); + return !GetScriptableFlag(); + } + return PR_TRUE; + } +#endif + + void SetScriptableFlag(PRBool on) + {mFlags.SetFlagBit(uint8(SCRIPTABLE),on);} + PRBool GetScriptableFlag() const + {return mFlags.GetFlagBit(uint8(SCRIPTABLE));} + + const nsID* GetTheIID() const {return &mIID;} + const char* GetTheName() const {return mName;} + + PRBool EnsureResolved(xptiWorkingSet* aWorkingSet = nsnull) + {return IsFullyResolved() ? PR_TRUE : Resolve(aWorkingSet);} + + PRBool PartiallyResolveLocked(XPTInterfaceDescriptor* aDescriptor, + xptiWorkingSet* aWorkingSet); + + nsresult GetInterfaceInfo(xptiInterfaceInfo** info); + PRBool InterfaceInfoEquals(const xptiInterfaceInfo* info) const + {return info == mInfo;} + + void LockedInvalidateInterfaceInfo(); + void LockedInterfaceInfoDeathNotification() {mInfo = nsnull;} + + ////////////////////// + // These non-virtual methods handle the delegated nsIInterfaceInfo methods. + + nsresult GetName(char * *aName); + nsresult GetIID(nsIID * *aIID); + nsresult IsScriptable(PRBool *_retval); + // Except this one. + //nsresult GetParent(nsIInterfaceInfo * *aParent); + nsresult GetMethodCount(PRUint16 *aMethodCount); + nsresult GetConstantCount(PRUint16 *aConstantCount); + nsresult GetMethodInfo(PRUint16 index, const nsXPTMethodInfo * *info); + nsresult GetMethodInfoForName(const char *methodName, PRUint16 *index, const nsXPTMethodInfo * *info); + nsresult GetConstant(PRUint16 index, const nsXPTConstant * *constant); + nsresult GetInfoForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIInterfaceInfo **_retval); + nsresult GetIIDForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID * *_retval); + nsresult GetTypeForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, nsXPTType *_retval); + nsresult GetSizeIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval); + nsresult GetLengthIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval); + nsresult GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint8 *_retval); + nsresult IsIID(const nsIID * IID, PRBool *_retval); + nsresult GetNameShared(const char **name); + nsresult GetIIDShared(const nsIID * *iid); + nsresult IsFunction(PRBool *_retval); + nsresult HasAncestor(const nsIID * iid, PRBool *_retval); + nsresult GetIIDForParamNoAlloc(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID *iid); + + ////////////////////// + +private: + xptiInterfaceEntry(); // not implemented + + xptiInterfaceEntry(const char* name, + size_t nameLength, + const nsID& iid, + const xptiTypelib& typelib); + + xptiInterfaceEntry(const xptiInterfaceEntry& r, + size_t nameLength, + const xptiTypelib& typelib); + ~xptiInterfaceEntry(); + + void* operator new(size_t, void* p) CPP_THROW_NEW {return p;} + + void SetResolvedState(int state) + {mFlags.SetState(uint8(state));} + + PRBool Resolve(xptiWorkingSet* aWorkingSet = nsnull); + + // We only call these "*Locked" variants after locking. This is done to + // allow reentrace as files are loaded and various interfaces resolved + // without having to worry about the locked state. + + PRBool EnsureResolvedLocked(xptiWorkingSet* aWorkingSet = nsnull) + {return IsFullyResolved() ? PR_TRUE : ResolveLocked(aWorkingSet);} + PRBool ResolveLocked(xptiWorkingSet* aWorkingSet = nsnull); + + // private helpers + + nsresult GetEntryForParam(PRUint16 methodIndex, + const nsXPTParamInfo * param, + xptiInterfaceEntry** entry); + + nsresult GetTypeInArray(const nsXPTParamInfo* param, + uint16 dimension, + const XPTTypeDescriptor** type); + +private: + nsID mIID; + union { + xptiTypelib mTypelib; // Valid only until resolved. + xptiInterfaceGuts* mInterface; // Valid only after resolved. + }; + xptiInterfaceInfo* mInfo; // May come and go. + xptiInfoFlags mFlags; + char mName[1]; // Always last. Sized to fit. +}; + +struct xptiHashEntry : public PLDHashEntryHdr +{ + xptiInterfaceEntry* value; +}; + +/****************************************************/ + +class xptiInterfaceInfo : public nsIInterfaceInfo +{ +public: + NS_DECL_ISUPPORTS + + // Use delegation to implement (most!) of nsIInterfaceInfo. + NS_IMETHOD GetName(char * *aName) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetName(aName); } + NS_IMETHOD GetInterfaceIID(nsIID * *aIID) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIID(aIID); } + NS_IMETHOD IsScriptable(PRBool *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsScriptable(_retval); } + // Except this one. + NS_IMETHOD GetParent(nsIInterfaceInfo * *aParent) + { + if(!EnsureResolved() || !EnsureParent()) + return NS_ERROR_UNEXPECTED; + NS_IF_ADDREF(*aParent = mParent); + return NS_OK; + } + NS_IMETHOD GetMethodCount(PRUint16 *aMethodCount) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetMethodCount(aMethodCount); } + NS_IMETHOD GetConstantCount(PRUint16 *aConstantCount) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetConstantCount(aConstantCount); } + NS_IMETHOD GetMethodInfo(PRUint16 index, const nsXPTMethodInfo * *info) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetMethodInfo(index, info); } + NS_IMETHOD GetMethodInfoForName(const char *methodName, PRUint16 *index, const nsXPTMethodInfo * *info) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetMethodInfoForName(methodName, index, info); } + NS_IMETHOD GetConstant(PRUint16 index, const nsXPTConstant * *constant) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetConstant(index, constant); } + NS_IMETHOD GetInfoForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIInterfaceInfo **_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetInfoForParam(methodIndex, param, _retval); } + NS_IMETHOD GetIIDForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID * *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIIDForParam(methodIndex, param, _retval); } + NS_IMETHOD GetTypeForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, nsXPTType *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetTypeForParam(methodIndex, param, dimension, _retval); } + NS_IMETHOD GetSizeIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetSizeIsArgNumberForParam(methodIndex, param, dimension, _retval); } + NS_IMETHOD GetLengthIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetLengthIsArgNumberForParam(methodIndex, param, dimension, _retval); } + NS_IMETHOD GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint8 *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetInterfaceIsArgNumberForParam(methodIndex, param, _retval); } + NS_IMETHOD IsIID(const nsIID * IID, PRBool *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsIID(IID, _retval); } + NS_IMETHOD GetNameShared(const char **name) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetNameShared(name); } + NS_IMETHOD GetIIDShared(const nsIID * *iid) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIIDShared(iid); } + NS_IMETHOD IsFunction(PRBool *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsFunction(_retval); } + NS_IMETHOD HasAncestor(const nsIID * iid, PRBool *_retval) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->HasAncestor(iid, _retval); } + NS_IMETHOD GetIIDForParamNoAlloc(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID *iid) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIIDForParamNoAlloc(methodIndex, param, iid); } + +public: + xptiInterfaceInfo(xptiInterfaceEntry* entry); + + void Invalidate() + {NS_IF_RELEASE(mParent); mEntry = nsnull;} + +#ifdef DEBUG + static void DEBUG_ShutdownNotification(); +#endif + +private: + + ~xptiInterfaceInfo(); + + // Note that mParent might still end up as nsnull if we don't have one. + PRBool EnsureParent(xptiWorkingSet* aWorkingSet = nsnull) + { + NS_ASSERTION(mEntry && mEntry->IsFullyResolved(), "bad EnsureParent call"); + return mParent || !mEntry->GetInterfaceGuts()->mParent || BuildParent(); + } + + PRBool EnsureResolved(xptiWorkingSet* aWorkingSet = nsnull) + { + return mEntry && mEntry->EnsureResolved(aWorkingSet); + } + + PRBool BuildParent() + { + NS_ASSERTION(mEntry && + mEntry->IsFullyResolved() && + !mParent && + mEntry->GetInterfaceGuts()->mParent, + "bad BuildParent call"); + return NS_SUCCEEDED(mEntry->GetInterfaceGuts()->mParent-> + GetInterfaceInfo(&mParent)); + } + + xptiInterfaceInfo(); // not implemented + +private: + xptiInterfaceEntry* mEntry; + xptiInterfaceInfo* mParent; +}; + +/***************************************************************************/ + +class xptiManifest +{ +public: + static PRBool Read(xptiInterfaceInfoManager* aMgr, + xptiWorkingSet* aWorkingSet); + + static PRBool Write(xptiInterfaceInfoManager* aMgr, + xptiWorkingSet* aWorkingSet); + + static PRBool Delete(xptiInterfaceInfoManager* aMgr); + +private: + xptiManifest(); // no implementation +}; + +/***************************************************************************/ + +class xptiZipLoaderSink : public nsIXPTLoaderSink +{ +public: + xptiZipLoaderSink(xptiInterfaceInfoManager* aMgr, + xptiWorkingSet* aWorkingSet) : + mManager(aMgr), + mWorkingSet(aWorkingSet) {} + + NS_DECL_ISUPPORTS + NS_DECL_NSIXPTLOADERSINK + +private: + ~xptiZipLoaderSink() {} + + xptiInterfaceInfoManager* mManager; + xptiWorkingSet* mWorkingSet; + +}; + +class xptiZipLoader +{ +public: + xptiZipLoader(); // not implemented + + static XPTHeader* + ReadXPTFileFromInputStream(nsIInputStream *stream, + xptiWorkingSet* aWorkingSet); + +}; + + +/***************************************************************************/ + +class xptiFileType +{ +public: + enum Type {UNKNOWN = -1, XPT = 0, ZIP = 1 }; + + static Type GetType(const char* name); + + static PRBool IsUnknown(const char* name) + {return GetType(name) == UNKNOWN;} + + static PRBool IsXPT(const char* name) + {return GetType(name) == XPT;} + + static PRBool IsZip(const char* name) + {return GetType(name) == ZIP;} +private: + xptiFileType(); // no implementation +}; + +/***************************************************************************/ + +// We use this is as a fancy way to open a logfile to be used within the scope +// of some given function where it is instantiated. + +class xptiAutoLog +{ +public: + xptiAutoLog(); // not implemented + xptiAutoLog(xptiInterfaceInfoManager* mgr, + nsILocalFile* logfile, PRBool append); + ~xptiAutoLog(); +private: + void WriteTimestamp(PRFileDesc* fd, const char* msg); + + xptiInterfaceInfoManager* mMgr; + PRFileDesc* mOldFileDesc; +#ifdef DEBUG + PRFileDesc* m_DEBUG_FileDesc; +#endif +}; + +/***************************************************************************/ + +class xptiInterfaceInfoManager + : public nsIInterfaceInfoSuperManager +{ + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERFACEINFOMANAGER + NS_DECL_NSIINTERFACEINFOSUPERMANAGER + + // helper + PRBool + FoundZipEntry(const char* entryName, + int index, + XPTHeader* header, + xptiWorkingSet* aWorkingSet); + +public: + static xptiInterfaceInfoManager* GetInterfaceInfoManagerNoAddRef(); + static void FreeInterfaceInfoManager(); + + xptiWorkingSet* GetWorkingSet() {return &mWorkingSet;} + PRFileDesc* GetOpenLogFile() {return mOpenLogFile;} + PRFileDesc* SetOpenLogFile(PRFileDesc* fd) + {PRFileDesc* temp = mOpenLogFile; mOpenLogFile = fd; return temp;} + + PRBool LoadFile(const xptiTypelib& aTypelibRecord, + xptiWorkingSet* aWorkingSet = nsnull); + + PRBool GetApplicationDir(nsILocalFile** aDir); + PRBool GetCloneOfManifestLocation(nsILocalFile** aDir); + + void GetSearchPath(nsISupportsArray** aSearchPath) + {NS_ADDREF(*aSearchPath = mSearchPath);} + + static PRLock* GetResolveLock(xptiInterfaceInfoManager* self = nsnull) + {if(!self && !(self = GetInterfaceInfoManagerNoAddRef())) + return nsnull; + return self->mResolveLock;} + + static PRLock* GetAutoRegLock(xptiInterfaceInfoManager* self = nsnull) + {if(!self && !(self = GetInterfaceInfoManagerNoAddRef())) + return nsnull; + return self->mAutoRegLock;} + + static PRMonitor* GetInfoMonitor(xptiInterfaceInfoManager* self = nsnull) + {if(!self && !(self = GetInterfaceInfoManagerNoAddRef())) + return nsnull; + return self->mInfoMonitor;} + + static void WriteToLog(const char *fmt, ...); + +private: + ~xptiInterfaceInfoManager(); + xptiInterfaceInfoManager(); // not implmented + xptiInterfaceInfoManager(nsISupportsArray* aSearchPath); + + enum AutoRegMode { + NO_FILES_CHANGED = 0, + FILES_ADDED_ONLY, + FULL_VALIDATION_REQUIRED + }; + + PRBool IsValid(); + + PRBool BuildFileList(nsISupportsArray* aSearchPath, + nsISupportsArray** aFileList); + + nsILocalFile** BuildOrderedFileArray(nsISupportsArray* aSearchPath, + nsISupportsArray* aFileList, + xptiWorkingSet* aWorkingSet); + + XPTHeader* ReadXPTFile(nsILocalFile* aFile, xptiWorkingSet* aWorkingSet); + + AutoRegMode DetermineAutoRegStrategy(nsISupportsArray* aSearchPath, + nsISupportsArray* aFileList, + xptiWorkingSet* aWorkingSet); + + PRBool AddOnlyNewFilesFromFileList(nsISupportsArray* aSearchPath, + nsISupportsArray* aFileList, + xptiWorkingSet* aWorkingSet); + + PRBool DoFullValidationMergeFromFileList(nsISupportsArray* aSearchPath, + nsISupportsArray* aFileList, + xptiWorkingSet* aWorkingSet); + + PRBool VerifyAndAddEntryIfNew(xptiWorkingSet* aWorkingSet, + XPTInterfaceDirectoryEntry* iface, + const xptiTypelib& typelibRecord, + xptiInterfaceEntry** entryAdded); + + PRBool MergeWorkingSets(xptiWorkingSet* aDestWorkingSet, + xptiWorkingSet* aSrcWorkingSet); + + void LogStats(); + + PRBool DEBUG_DumpFileList(nsISupportsArray* aFileList); + PRBool DEBUG_DumpFileArray(nsILocalFile** aFileArray, PRUint32 count); + PRBool DEBUG_DumpFileListInWorkingSet(xptiWorkingSet* aWorkingSet); + + static PRBool BuildFileSearchPath(nsISupportsArray** aPath); + +private: + xptiWorkingSet mWorkingSet; + nsCOMPtr<nsILocalFile> mStatsLogFile; + nsCOMPtr<nsILocalFile> mAutoRegLogFile; + PRFileDesc* mOpenLogFile; + PRLock* mResolveLock; + PRLock* mAutoRegLock; + PRMonitor* mInfoMonitor; + PRLock* mAdditionalManagersLock; + nsSupportsArray mAdditionalManagers; + nsCOMPtr<nsISupportsArray> mSearchPath; +}; + +/***************************************************************************/ +// utilities... + +nsresult xptiCloneLocalFile(nsILocalFile* aLocalFile, + nsILocalFile** aCloneLocalFile); + +nsresult xptiCloneElementAsLocalFile(nsISupportsArray* aArray, PRUint32 aIndex, + nsILocalFile** aLocalFile); + +#endif /* xptiprivate_h___ */ diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/tests/.cvsignore b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/tests/.cvsignore new file mode 100644 index 00000000..f29041e6 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/tests/.cvsignore @@ -0,0 +1,2 @@ +Makefile +TestInterfaceInfo diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/tests/Makefile.in b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/tests/Makefile.in new file mode 100644 index 00000000..9b7f1ed4 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/tests/Makefile.in @@ -0,0 +1,58 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom + +SIMPLE_PROGRAMS = TestInterfaceInfo$(BIN_SUFFIX) + +CPPSRCS = TestInterfaceInfo.cpp + +LIBS = \ + $(XPCOM_LIBS) \ + $(NSPR_LIBS) \ + $(NULL) + +include $(topsrcdir)/config/rules.mk + +DEFINES += -DEXPORT_XPTI_API diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/tests/TestInterfaceInfo.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/tests/TestInterfaceInfo.cpp new file mode 100644 index 00000000..75005c50 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/tests/TestInterfaceInfo.cpp @@ -0,0 +1,146 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Some simple smoke tests of the typelib loader. */ + +#include "nscore.h" + +#include "nsISupports.h" +#include "nsIInterfaceInfo.h" +#include "nsIInterfaceInfoManager.h" +#include "xptinfo.h" + +#include <stdio.h> + +// This file expects the nsInterfaceInfoManager to be able to discover +// .xpt files corresponding to those in xpcom/idl. Currently this +// means setting XPTDIR in the environment to some directory +// containing these files. + +int main (int argc, char **argv) { + int i; + nsIID *iid1, *iid2, *iid3; + char *name1, *name2, *name3; + nsIInterfaceInfo *info2, *info3, *info4, *info5; + + nsIInterfaceInfoManager *iim = XPTI_GetInterfaceInfoManager(); + + fprintf(stderr, "\ngetting iid for 'nsISupports'\n"); + iim->GetIIDForName("nsISupports", &iid1); + iim->GetNameForIID(iid1, &name1); + fprintf(stderr, "%s iid %s\n", name1, iid1->ToString()); + + fprintf(stderr, "\ngetting iid for 'nsIInputStream'\n"); + iim->GetIIDForName("nsIInputStream", &iid2); + iim->GetNameForIID(iid2, &name2); + fprintf(stderr, "%s iid %s\n", name2, iid2->ToString()); + + fprintf(stderr, "iid: %s, name: %s\n", iid1->ToString(), name1); + fprintf(stderr, "iid: %s, name: %s\n", iid2->ToString(), name2); + + fprintf(stderr, "\ngetting info for iid2 from above\n"); + iim->GetInfoForIID(iid2, &info2); +#ifdef DEBUG +// ((nsInterfaceInfo *)info2)->print(stderr); +#endif + + fprintf(stderr, "\ngetting iid for 'nsIInputStream'\n"); + iim->GetIIDForName("nsIInputStream", &iid3); + iim->GetNameForIID(iid3, &name3); + fprintf(stderr, "%s iid %s\n", name3, iid2->ToString()); + iim->GetInfoForIID(iid3, &info3); +#ifdef DEBUG +// ((nsInterfaceInfo *)info3)->print(stderr); +#endif + + fprintf(stderr, "\ngetting info for name 'nsIBidirectionalEnumerator'\n"); + iim->GetInfoForName("nsIBidirectionalEnumerator", &info4); +#ifdef DEBUG +// ((nsInterfaceInfo *)info4)->print(stderr); +#endif + + fprintf(stderr, "\nparams work?\n"); + fprintf(stderr, "\ngetting info for name 'nsIServiceManager'\n"); + iim->GetInfoForName("nsIServiceManager", &info5); +#ifdef DEBUG +// ((nsInterfaceInfo *)info5)->print(stderr); +#endif + + // XXX: nsIServiceManager is no more; what do we test with? + if (info5 == NULL) { + fprintf(stderr, "\nNo nsIServiceManager; cannot continue.\n"); + return 1; + } + + uint16 methodcount; + info5->GetMethodCount(&methodcount); + const nsXPTMethodInfo *mi; + for (i = 0; i < methodcount; i++) { + info5->GetMethodInfo(i, &mi); + fprintf(stderr, "method %d, name %s\n", i, mi->GetName()); + } + + // 7 is GetServiceWithListener, which has juicy params. + info5->GetMethodInfo(7, &mi); +// uint8 paramcount = mi->GetParamCount(); + + nsXPTParamInfo param2 = mi->GetParam(2); + // should be IID for nsIShutdownListener + nsIID *nsISL; + info5->GetIIDForParam(7, ¶m2, &nsISL); +// const nsIID *nsISL = param2.GetInterfaceIID(info5); + fprintf(stderr, "iid assoc'd with param 2 of method 7 of GetServiceWithListener - %s\n", nsISL->ToString()); + // if we look up the name? + char *nsISLname; + iim->GetNameForIID(nsISL, &nsISLname); + fprintf(stderr, "which is called %s\n", nsISLname); + + fprintf(stderr, "\nhow about one defined in a different typelib\n"); + nsXPTParamInfo param3 = mi->GetParam(3); + // should be IID for nsIShutdownListener + nsIID *nsISS; + info5->GetIIDForParam(7, ¶m3, &nsISS); +// const nsIID *nsISS = param3.GetInterfaceIID(info5); + fprintf(stderr, "iid assoc'd with param 3 of method 7 of GetServiceWithListener - %s\n", nsISS->ToString()); + // if we look up the name? + char *nsISSname; + iim->GetNameForIID(nsISS, &nsISSname); + fprintf(stderr, "which is called %s\n", nsISSname); + + return 0; +} + |