Back to index

lightning-sunbird  0.9+nobinonly
xptcinvoke_x86_solaris.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org Code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1999
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 /* Platform specific code to invoke XPCOM methods on native objects */
00040 
00041 #include "xptcprivate.h"
00042 #include "xptc_platforms_unixish_x86.h"
00043 
00044 extern "C" {
00045 
00046 // Remember that these 'words' are 32bit DWORDS
00047 
00048 #if !defined(__SUNPRO_CC)               /* Sun Workshop Compiler. */
00049 static
00050 #endif
00051 PRUint32
00052 invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s)
00053 {
00054     PRUint32 result = 0;
00055     for(PRUint32 i = 0; i < paramCount; i++, s++)
00056     {
00057         if(s->IsPtrData())
00058         {
00059             result++;
00060             continue;
00061         }
00062         result++;
00063         switch(s->type)
00064         {
00065         case nsXPTType::T_I64    :
00066         case nsXPTType::T_U64    :
00067         case nsXPTType::T_DOUBLE :
00068             result++;
00069             break;
00070         }
00071     }
00072     return result;
00073 }
00074 
00075 #if !defined(__SUNPRO_CC)               /* Sun Workshop Compiler. */
00076 static
00077 #endif
00078 void
00079 invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d)
00080 {
00081     for(PRUint32 i = 0; i < paramCount; i++, d++, s++)
00082     {
00083         if(s->IsPtrData())
00084         {
00085             *((void**)d) = s->ptr;
00086             continue;
00087         }
00088 
00089 /* XXX: the following line is here (rather than as the default clause in
00090  *      the following switch statement) so that the Sun native compiler
00091  *      will generate the correct assembly code on the Solaris Intel
00092  *      platform. See the comments in bug #28817 for more details.
00093  */
00094 
00095         *((void**)d) = s->val.p;
00096 
00097         switch(s->type)
00098         {
00099         case nsXPTType::T_I64    : *((PRInt64*) d) = s->val.i64; d++;    break;
00100         case nsXPTType::T_U64    : *((PRUint64*)d) = s->val.u64; d++;    break;
00101         case nsXPTType::T_DOUBLE : *((double*)  d) = s->val.d;   d++;    break;
00102         }
00103     }
00104 }
00105 
00106 }
00107 
00108 #if !defined(__SUNPRO_CC)               /* Sun Workshop Compiler. */
00109 XPTC_PUBLIC_API(nsresult)
00110 XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
00111                    PRUint32 paramCount, nsXPTCVariant* params)
00112 {
00113 #ifdef __GNUC__            /* Gnu compiler. */
00114   PRUint32 result;
00115   PRUint32 n = invoke_count_words (paramCount, params) * 4;
00116   void (*fn_copy) (unsigned int, nsXPTCVariant *, PRUint32 *) = invoke_copy_to_stack;
00117   int temp1, temp2, temp3;
00118  
00119  __asm__ __volatile__(
00120     "subl  %8, %%esp\n\t" /* make room for params */
00121     "pushl %%esp\n\t"
00122     "pushl %7\n\t"
00123     "pushl %6\n\t"
00124     "call  *%0\n\t"       /* copy params */
00125     "addl  $0xc, %%esp\n\t"
00126     "movl  %4, %%ecx\n\t"
00127 #ifdef CFRONT_STYLE_THIS_ADJUST
00128     "movl  (%%ecx), %%edx\n\t"
00129     "movl  %5, %%eax\n\t"   /* function index */
00130     "shl   $3, %%eax\n\t"   /* *= 8 */
00131     "addl  $8, %%eax\n\t"   /* += 8 skip first entry */
00132     "addl  %%eax, %%edx\n\t"
00133     "movswl (%%edx), %%eax\n\t" /* 'this' offset */
00134     "addl  %%eax, %%ecx\n\t"
00135     "pushl %%ecx\n\t"
00136     "addl  $4, %%edx\n\t"   /* += 4, method pointer */
00137 #else /* THUNK_BASED_THIS_ADJUST */
00138     "pushl %%ecx\n\t"
00139     "movl  (%%ecx), %%edx\n\t"
00140     "movl  %5, %%eax\n\t"   /* function index */
00141 #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */
00142     "leal  (%%edx,%%eax,4), %%edx\n\t"
00143 #else /* not G++ V3 ABI  */
00144     "leal  8(%%edx,%%eax,4), %%edx\n\t"
00145 #endif /* G++ V3 ABI */
00146 #endif
00147     "call  *(%%edx)\n\t"    /* safe to not cleanup esp */
00148     "addl  $4, %%esp\n\t"
00149     "addl  %8, %%esp"
00150     : "=a" (result),        /* %0 */
00151       "=c" (temp1),         /* %1 */
00152       "=d" (temp2),         /* %2 */
00153       "=g" (temp3)          /* %3 */
00154     : "g" (that),           /* %4 */
00155       "g" (methodIndex),    /* %5 */
00156       "1" (paramCount),     /* %6 */
00157       "2" (params),         /* %7 */
00158       "g" (n),              /* %8 */
00159       "0" (fn_copy)         /* %3 */
00160     : "memory"
00161     );
00162     
00163   return result;
00164 #else
00165 #error "can't find a compiler to use"
00166 #endif /* __GNUC__ */
00167 
00168 }
00169 #endif