1 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Mark Mentovai <mark@moxienet.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : /* Platform specific code to invoke XPCOM methods on native objects */
40 :
41 : #include "xptcprivate.h"
42 : #include "xptc_gcc_x86_unix.h"
43 :
44 : extern "C" {
45 : static void ATTRIBUTE_USED __attribute__ ((regparm(3)))
46 6669618 : invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d)
47 : {
48 17883146 : for(PRUint32 i = paramCount; i >0; i--, d++, s++)
49 : {
50 11213528 : if(s->IsPtrData())
51 : {
52 4210340 : *((void**)d) = s->ptr;
53 4210340 : continue;
54 : }
55 :
56 7003188 : switch(s->type)
57 : {
58 12886 : case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break;
59 9642 : case nsXPTType::T_U64 : *((PRUint64*)d) = s->val.u64; d++; break;
60 3 : case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; break;
61 6980657 : default : *((void**)d) = s->val.p; break;
62 : }
63 : }
64 6669618 : }
65 : } // extern "C"
66 :
67 : /*
68 : EXPORT_XPCOM_API(nsresult)
69 : NS_InvokeByIndex_P(nsISupports* that, PRUint32 methodIndex,
70 : PRUint32 paramCount, nsXPTCVariant* params);
71 :
72 : Each param takes at most two 4-byte words.
73 : It doesn't matter if we push too many words, and calculating the exact
74 : amount takes time.
75 :
76 : that = ebp + 0x08
77 : methodIndex = ebp + 0x0c
78 : paramCount = ebp + 0x10
79 : params = ebp + 0x14
80 :
81 : */
82 :
83 : __asm__ (
84 : ".text\n\t"
85 : /* alignment here seems unimportant here; this was 16, now it's 2 which
86 : is what xptcstubs uses. */
87 : ".align 2\n\t"
88 : ".globl " SYMBOL_UNDERSCORE "NS_InvokeByIndex_P\n\t"
89 : #ifndef XP_MACOSX
90 : ".type " SYMBOL_UNDERSCORE "NS_InvokeByIndex_P,@function\n"
91 : #endif
92 : SYMBOL_UNDERSCORE "NS_InvokeByIndex_P:\n\t"
93 : "pushl %ebp\n\t"
94 : "movl %esp, %ebp\n\t"
95 : "movl 0x10(%ebp), %eax\n\t"
96 : "leal 0(,%eax,8),%edx\n\t"
97 :
98 : /* set up call frame for method. */
99 : "subl %edx, %esp\n\t" /* make room for params. */
100 : /* Align to maximum x86 data size: 128 bits == 16 bytes == XMM register size.
101 : * This is to avoid protection faults where SSE+ alignment of stack pointer
102 : * is assumed and required, e.g. by GCC4's -ftree-vectorize option.
103 : */
104 : "andl $0xfffffff0, %esp\n\t" /* drop(?) stack ptr to 128-bit align */
105 : /* $esp should be aligned to a 16-byte boundary here (note we include an
106 : * additional 4 bytes in a later push instruction). This will ensure $ebp
107 : * in the function called below is aligned to a 0x8 boundary. SSE instructions
108 : * like movapd/movdqa expect memory operand to be aligned on a 16-byte
109 : * boundary. The GCC compiler will generate the memory operand using $ebp
110 : * with an 8-byte offset.
111 : */
112 : "subl $0xc, %esp\n\t" /* lower again; push/call below will re-align */
113 : "movl %esp, %ecx\n\t" /* ecx = d */
114 : "movl 8(%ebp), %edx\n\t" /* edx = this */
115 : "pushl %edx\n\t" /* push this. esp % 16 == 0 */
116 :
117 : "movl 0x14(%ebp), %edx\n\t"
118 : "call " SYMBOL_UNDERSCORE "invoke_copy_to_stack\n\t"
119 : "movl 0x08(%ebp), %ecx\n\t" /* 'that' */
120 : "movl (%ecx), %edx\n\t"
121 : "movl 0x0c(%ebp), %eax\n\t" /* function index */
122 : "leal (%edx,%eax,4), %edx\n\t"
123 : "call *(%edx)\n\t"
124 : "movl %ebp, %esp\n\t"
125 : "popl %ebp\n\t"
126 : "ret\n"
127 : #ifndef XP_MACOSX
128 : ".size " SYMBOL_UNDERSCORE "NS_InvokeByIndex_P, . -" SYMBOL_UNDERSCORE "NS_InvokeByIndex_P\n\t"
129 : #endif
130 : );
|