Back to index

lightning-sunbird  0.9+nobinonly
xptcinvoke_gcc_x86_unix.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /* Platform specific code to invoke XPCOM methods on native objects */
00039 
00040 #ifdef __GNUC__            /* Gnu compiler. */
00041 
00042 #include "xptcprivate.h"
00043 #include "xptc_platforms_unixish_x86.h"
00044 #include "xptc_gcc_x86_unix.h"
00045 
00046 extern "C" {
00047 #ifndef XP_WIN32
00048 static
00049 #endif
00050 void ATTRIBUTE_USED __attribute__ ((regparm(3)))
00051 invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d)
00052 {
00053     for(PRUint32 i = paramCount; i >0; i--, d++, s++)
00054     {
00055         if(s->IsPtrData())
00056         {
00057             *((void**)d) = s->ptr;
00058             continue;
00059         }
00060 
00061         switch(s->type)
00062         {
00063         case nsXPTType::T_I64    : *((PRInt64*) d) = s->val.i64; d++;    break;
00064         case nsXPTType::T_U64    : *((PRUint64*)d) = s->val.u64; d++;    break;
00065         case nsXPTType::T_DOUBLE : *((double*)  d) = s->val.d;   d++;    break;
00066         default                  : *((void**)d)    = s->val.p;           break;
00067         }
00068     }
00069 }
00070 } // extern "C"
00071 
00072 // NOTE! See xptc_gcc_x86_unix.h for the reason why this function exists.
00073 #if (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ == 0))
00074 PRUint32
00075 xptc_invoke_copy_to_stack_keeper (void)
00076 {
00077     PRUint32 dummy1;
00078     void ATTRIBUTE_USED __attribute__ ((regparm(3))) (*dummy2)
00079        (PRUint32, nsXPTCVariant*, PRUint32*) = invoke_copy_to_stack;
00080 
00081 // dummy2 references invoke_copy_to_stack, now we have to "use" it
00082     __asm__ __volatile__ (
00083        ""
00084        : "=&a" (dummy1)
00085        : "g"   (dummy2)
00086     );
00087 
00088     return dummy1 & 0xF0F00000;
00089 }
00090 #endif
00091 
00092 
00093 /*
00094   XPTC_PUBLIC_API(nsresult)
00095   XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
00096                    PRUint32 paramCount, nsXPTCVariant* params);
00097 
00098   Each param takes at most two 4-byte words.
00099   It doesn't matter if we push too many words, and calculating the exact
00100   amount takes time.
00101 
00102   that        = ebp + 0x08
00103   methodIndex = ebp + 0x0c
00104   paramCount  = ebp + 0x10
00105   params      = ebp + 0x14
00106 
00107   NOTE NOTE NOTE:
00108   As of 2002-04-29 this function references no global variables nor does
00109   it call non-static functions so preserving and loading the PIC register
00110   is unnecessary. Define MOZ_PRESERVE_PIC if this changes. See mozilla
00111   bug 140412 for details. However, avoid this if you can. It's slower.
00112 */
00113 /*
00114  * Hack for gcc for win32.  Functions used externally must be
00115  * explicitly dllexported.
00116  * Bug 226609
00117  */
00118 #ifdef XP_WIN32
00119 extern "C" {
00120     nsresult _XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
00121                                    PRUint32 paramCount, nsXPTCVariant* params);
00122     XPTC_PUBLIC_API(nsresult)
00123          XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
00124                             PRUint32 paramCount, nsXPTCVariant* params) { 
00125         return _XPTC_InvokeByIndex(that, methodIndex, paramCount, params);
00126     }
00127 }
00128 #endif
00129 
00130 __asm__ (
00131        ".text\n\t"
00132 /* alignment here seems unimportant here; this was 16, now it's 2 which
00133    is what xptcstubs uses. */
00134        ".align 2\n\t"
00135 #ifdef XP_WIN32
00136        ".globl " SYMBOL_UNDERSCORE "_XPTC_InvokeByIndex\n\t"
00137        SYMBOL_UNDERSCORE "_XPTC_InvokeByIndex:\n\t"
00138 #else
00139        ".globl " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex\n\t"
00140        ".type  " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex,@function\n"
00141        SYMBOL_UNDERSCORE "XPTC_InvokeByIndex:\n\t"
00142 #endif
00143        "pushl %ebp\n\t"
00144        "movl  %esp, %ebp\n\t"
00145 #ifdef MOZ_PRESERVE_PIC 
00146        "pushl %ebx\n\t"
00147        "call  0f\n\t"
00148        ".subsection 1\n"
00149        "0:\n\t"
00150        "movl (%esp), %ebx\n\t"
00151        "ret\n\t"
00152        ".previous\n\t"
00153        "addl  $_GLOBAL_OFFSET_TABLE_, %ebx\n\t"
00154 #endif
00155        "movl  0x10(%ebp), %eax\n\t"
00156        "leal  0(,%eax,8),%edx\n\t"
00157        "movl  %esp, %ecx\n\t"
00158        "subl  %edx, %ecx\n\t"
00159 /* Since there may be 64-bit data, it occurs to me that aligning this
00160    space might be a performance gain. However, I don't think the rest
00161    of mozilla worries about such things. In any event, do it here.
00162        "andl  $0xfffffff8, %ecx\n\t"
00163  */
00164        "movl  %ecx, %esp\n\t"          /* make stack space */
00165        "movl  0x14(%ebp), %edx\n\t"
00166        "call  " SYMBOL_UNDERSCORE "invoke_copy_to_stack\n\t"
00167        "movl  0x08(%ebp), %ecx\n\t"       /* 'that' */
00168 #ifdef CFRONT_STYLE_THIS_ADJUST
00169        "movl  (%ecx), %edx\n\t"
00170        "movl  0x0c(%ebp), %eax\n\t"    /* function index */
00171        "shll  $3, %eax\n\t"         /* *= 8 */
00172        "addl  $8, %eax\n\t"         /* += 8 skip first entry */
00173        "addl  %eax, %edx\n\t"
00174        "movswl (%edx), %eax\n\t"       /* 'this' offset */
00175        "addl  %eax, %ecx\n\t"
00176        "pushl %ecx\n\t"
00177        "addl  $4, %edx\n\t"         /* += 4, method pointer */
00178 #else /* THUNK_BASED_THIS_ADJUST */
00179        "pushl %ecx\n\t"
00180        "movl  (%ecx), %edx\n\t"
00181        "movl  0x0c(%ebp), %eax\n\t"    /* function index */
00182 #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */
00183        "leal  (%edx,%eax,4), %edx\n\t"
00184 #else /* not G++ V3 ABI  */
00185        "leal  8(%edx,%eax,4), %edx\n\t"
00186 #endif /* G++ V3 ABI */
00187 #endif
00188        "call  *(%edx)\n\t"
00189 #ifdef MOZ_PRESERVE_PIC
00190        "movl  -4(%ebp), %ebx\n\t"
00191 #endif
00192        "movl  %ebp, %esp\n\t"
00193        "popl  %ebp\n\t"
00194        "ret\n"
00195 #ifndef XP_WIN32
00196        ".size " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex, . -" SYMBOL_UNDERSCORE "XPTC_InvokeByIndex\n\t"
00197 #endif
00198 );
00199 
00200 #else
00201 #error "can't find a compiler to use"
00202 #endif /* __GNUC__ */