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) 1999
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Benjamin Smedberg <benjamin@smedbergs.us>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * 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 : /* Public declarations for xptcall. */
40 :
41 : #ifndef xptcall_h___
42 : #define xptcall_h___
43 :
44 : #ifdef MOZILLA_INTERNAL_API
45 : # define NS_GetXPTCallStub NS_GetXPTCallStub_P
46 : # define NS_DestroyXPTCallStub NS_DestroyXPTCallStub_P
47 : # define NS_InvokeByIndex NS_InvokeByIndex_P
48 : #endif
49 :
50 : #include "prtypes.h"
51 : #include "nscore.h"
52 : #include "nsISupports.h"
53 : #include "xpt_struct.h"
54 : #include "xptinfo.h"
55 : #include "jsapi.h"
56 :
57 : struct nsXPTCMiniVariant
58 11359143 : {
59 : // No ctors or dtors so that we can use arrays of these on the stack
60 : // with no penalty.
61 : union
62 : {
63 : PRInt8 i8;
64 : PRInt16 i16;
65 : PRInt32 i32;
66 : PRInt64 i64;
67 : PRUint8 u8;
68 : PRUint16 u16;
69 : PRUint32 u32;
70 : PRUint64 u64;
71 : float f;
72 : double d;
73 : bool b;
74 : char c;
75 : PRUnichar wc;
76 : void* p;
77 :
78 : // Types below here are unknown to the assembly implementations, and
79 : // therefore _must_ be passed with indirect semantics. We put them in
80 : // the union here for type safety, so that we can avoid void* tricks.
81 : jsval j;
82 : } val;
83 : };
84 :
85 : struct nsXPTCVariant : public nsXPTCMiniVariant
86 22572782 : {
87 : // No ctors or dtors so that we can use arrays of these on the stack
88 : // with no penalty.
89 :
90 : // inherits 'val' here
91 : void* ptr;
92 : nsXPTType type;
93 : PRUint8 flags;
94 :
95 : enum
96 : {
97 : //
98 : // Bitflag definitions
99 : //
100 :
101 : // Indicates that ptr (above, and distinct from val.p) is the value that
102 : // should be passed on the stack.
103 : //
104 : // In theory, ptr could point anywhere. But in practice it always points
105 : // to &val. So this flag is used to pass 'val' by reference, letting us
106 : // avoid the extra allocation we would incur if we were to use val.p.
107 : //
108 : // Various parts of XPConnect assume that ptr==&val, so we enforce it
109 : // explicitly with SetIndirect() and IsIndirect().
110 : //
111 : // Since ptr always points to &val, the semantics of this flag are kind of
112 : // dumb, since the ptr field is unnecessary. But changing them would
113 : // require changing dozens of assembly files, so they're likely to stay
114 : // the way they are.
115 : PTR_IS_DATA = 0x1,
116 :
117 : // Indicates that the value we hold requires some sort of cleanup (memory
118 : // deallocation, interface release, jsval unrooting, etc). The precise
119 : // cleanup that is performed depends on the 'type' field above.
120 : // If the value is an array, this flag specifies whether the elements
121 : // within the array require cleanup (we always clean up the array itself,
122 : // so this flag would be redundant for that purpose).
123 : VAL_NEEDS_CLEANUP = 0x2
124 : };
125 :
126 11213639 : void ClearFlags() {flags = 0;}
127 4210377 : void SetIndirect() {ptr = &val; flags |= PTR_IS_DATA;}
128 7438460 : void SetValNeedsCleanup() {flags |= VAL_NEEDS_CLEANUP;}
129 :
130 : bool IsIndirect() const {return 0 != (flags & PTR_IS_DATA);}
131 10791605 : bool DoesValNeedCleanup() const {return 0 != (flags & VAL_NEEDS_CLEANUP);}
132 :
133 : // Internal use only. Use IsIndirect() instead.
134 11213528 : bool IsPtrData() const {return 0 != (flags & PTR_IS_DATA);}
135 :
136 5 : void Init(const nsXPTCMiniVariant& mv, const nsXPTType& t, PRUint8 f)
137 : {
138 5 : type = t;
139 5 : flags = f;
140 :
141 5 : if(f & PTR_IS_DATA)
142 : {
143 3 : ptr = mv.val.p;
144 3 : val.p = nsnull;
145 : }
146 : else
147 : {
148 2 : ptr = nsnull;
149 2 : val.p = nsnull; // make sure 'val.p' is always initialized
150 2 : switch(t.TagPart()) {
151 0 : case nsXPTType::T_I8: val.i8 = mv.val.i8; break;
152 0 : case nsXPTType::T_I16: val.i16 = mv.val.i16; break;
153 0 : case nsXPTType::T_I32: val.i32 = mv.val.i32; break;
154 0 : case nsXPTType::T_I64: val.i64 = mv.val.i64; break;
155 0 : case nsXPTType::T_U8: val.u8 = mv.val.u8; break;
156 0 : case nsXPTType::T_U16: val.u16 = mv.val.u16; break;
157 2 : case nsXPTType::T_U32: val.u32 = mv.val.u32; break;
158 0 : case nsXPTType::T_U64: val.u64 = mv.val.u64; break;
159 0 : case nsXPTType::T_FLOAT: val.f = mv.val.f; break;
160 0 : case nsXPTType::T_DOUBLE: val.d = mv.val.d; break;
161 0 : case nsXPTType::T_BOOL: val.b = mv.val.b; break;
162 0 : case nsXPTType::T_CHAR: val.c = mv.val.c; break;
163 0 : case nsXPTType::T_WCHAR: val.wc = mv.val.wc; break;
164 : case nsXPTType::T_VOID: /* fall through */
165 : case nsXPTType::T_IID: /* fall through */
166 : case nsXPTType::T_DOMSTRING: /* fall through */
167 : case nsXPTType::T_CHAR_STR: /* fall through */
168 : case nsXPTType::T_WCHAR_STR: /* fall through */
169 : case nsXPTType::T_INTERFACE: /* fall through */
170 : case nsXPTType::T_INTERFACE_IS: /* fall through */
171 : case nsXPTType::T_ARRAY: /* fall through */
172 : case nsXPTType::T_PSTRING_SIZE_IS: /* fall through */
173 : case nsXPTType::T_PWSTRING_SIZE_IS: /* fall through */
174 : case nsXPTType::T_UTF8STRING: /* fall through */
175 : case nsXPTType::T_CSTRING: /* fall through */
176 0 : default: val.p = mv.val.p; break;
177 : }
178 : }
179 5 : }
180 : };
181 :
182 : class nsIXPTCProxy : public nsISupports
183 106804 : {
184 : public:
185 : NS_IMETHOD CallMethod(PRUint16 aMethodIndex,
186 : const XPTMethodDescriptor *aInfo,
187 : nsXPTCMiniVariant *aParams) = 0;
188 : };
189 :
190 : /**
191 : * This is a typedef to avoid confusion between the canonical
192 : * nsISupports* that provides object identity and an interface pointer
193 : * for inheriting interfaces that aren't known at compile-time.
194 : */
195 : typedef nsISupports nsISomeInterface;
196 :
197 : /**
198 : * Get a proxy object to implement the specified interface.
199 : *
200 : * @param aIID The IID of the interface to implement.
201 : * @param aOuter An object to receive method calls from the proxy object.
202 : * The stub forwards QueryInterface/AddRef/Release to the
203 : * outer object. The proxy object does not hold a reference to
204 : * the outer object; it is the caller's responsibility to
205 : * ensure that this pointer remains valid until the stub has
206 : * been destroyed.
207 : * @param aStub Out parameter for the new proxy object. The object is
208 : * not addrefed. The object never destroys itself. It must be
209 : * explicitly destroyed by calling
210 : * NS_DestroyXPTCallStub when it is no longer needed.
211 : */
212 : XPCOM_API(nsresult)
213 : NS_GetXPTCallStub(REFNSIID aIID, nsIXPTCProxy* aOuter,
214 : nsISomeInterface* *aStub);
215 :
216 : /**
217 : * Destroys an XPTCall stub previously created with NS_GetXPTCallStub.
218 : */
219 : XPCOM_API(void)
220 : NS_DestroyXPTCallStub(nsISomeInterface* aStub);
221 :
222 : XPCOM_API(nsresult)
223 : NS_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
224 : PRUint32 paramCount, nsXPTCVariant* params);
225 :
226 : #endif /* xptcall_h___ */
|