1 |
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
2 |
* vim: set ts=8 sw=4 et tw=99: |
3 |
* |
4 |
* ***** BEGIN LICENSE BLOCK ***** |
5 |
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
6 |
* |
7 |
* The contents of this file are subject to the Mozilla Public License Version |
8 |
* 1.1 (the "License"); you may not use this file except in compliance with |
9 |
* the License. You may obtain a copy of the License at |
10 |
* http://www.mozilla.org/MPL/ |
11 |
* |
12 |
* Software distributed under the License is distributed on an "AS IS" basis, |
13 |
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
14 |
* for the specific language governing rights and limitations under the |
15 |
* License. |
16 |
* |
17 |
* The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released |
18 |
* May 28, 2008. |
19 |
* |
20 |
* The Initial Developer of the Original Code is |
21 |
* Mozilla Corporation. |
22 |
* |
23 |
* Contributor(s): |
24 |
* Jason Orendorff <jorendorff@mozilla.com> |
25 |
* |
26 |
* Alternatively, the contents of this file may be used under the terms of |
27 |
* either of the GNU General Public License Version 2 or later (the "GPL"), |
28 |
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
29 |
* in which case the provisions of the GPL or the LGPL are applicable instead |
30 |
* of those above. If you wish to allow use of your version of this file only |
31 |
* under the terms of either the GPL or the LGPL, and not to allow others to |
32 |
* use your version of this file under the terms of the MPL, indicate your |
33 |
* decision by deleting the provisions above and replace them with the notice |
34 |
* and other provisions required by the GPL or the LGPL. If you do not delete |
35 |
* the provisions above, a recipient may use your version of this file under |
36 |
* the terms of any one of the MPL, the GPL or the LGPL. |
37 |
* |
38 |
* ***** END LICENSE BLOCK ***** */ |
39 |
|
40 |
#ifndef jsbuiltins_h___ |
41 |
#define jsbuiltins_h___ |
42 |
|
43 |
#ifdef JS_TRACER |
44 |
|
45 |
#include "nanojit/nanojit.h" |
46 |
#include "jstracer.h" |
47 |
|
48 |
enum JSTNErrType { INFALLIBLE, FAIL_STATUS, FAIL_NULL, FAIL_NEG, FAIL_VOID, FAIL_COOKIE }; |
49 |
enum { JSTN_ERRTYPE_MASK = 0x07, JSTN_UNBOX_AFTER = 0x08, JSTN_MORE = 0x10, |
50 |
JSTN_CONSTRUCTOR = 0x20 }; |
51 |
|
52 |
#define JSTN_ERRTYPE(jstn) ((jstn)->flags & JSTN_ERRTYPE_MASK) |
53 |
|
54 |
/* |
55 |
* |prefix| and |argtypes| declare what arguments should be passed to the |
56 |
* native function. |prefix| can contain the following characters: |
57 |
* |
58 |
* 'C': a JSContext* argument |
59 |
* 'T': |this| as a JSObject* argument (bails if |this| is not an object) |
60 |
* 'S': |this| as a JSString* argument (bails if |this| is not a string) |
61 |
* 'R': a JSRuntime* argument |
62 |
* 'P': the pc as a jsbytecode* |
63 |
* 'D': |this| as a number (jsdouble) |
64 |
* 'f': the function being called, as a JSObject* |
65 |
* 'p': the .prototype of the function, as a JSObject* |
66 |
* |
67 |
* The corresponding things will get passed as arguments to the builtin in |
68 |
* reverse order (so TC means JSContext* as the first arg, and the |
69 |
* JSObject* for |this| as the second arg). |
70 |
* |
71 |
* |argtypes| can contain the following characters: |
72 |
* 'd': a number (double) argument |
73 |
* 'i': an integer argument |
74 |
* 's': a JSString* argument |
75 |
* 'o': a JSObject* argument |
76 |
* 'r': a JSObject* argument that is of class js_RegExpClass |
77 |
* 'f': a JSObject* argument that is of class js_FunctionClass |
78 |
* 'v': a jsval argument (boxing whatever value is actually being passed in) |
79 |
*/ |
80 |
struct JSTraceableNative { |
81 |
JSFastNative native; |
82 |
const nanojit::CallInfo *builtin; |
83 |
const char *prefix; |
84 |
const char *argtypes; |
85 |
uintN flags; /* JSTNErrType | JSTN_UNBOX_AFTER | JSTN_MORE | |
86 |
JSTN_CONSTRUCTOR */ |
87 |
}; |
88 |
|
89 |
/* |
90 |
* We use a magic boxed pointer value to represent error conditions that |
91 |
* trigger a side exit. The address is so low that it should never be actually |
92 |
* in use. If it is, a performance regression occurs, not an actual runtime |
93 |
* error. |
94 |
*/ |
95 |
#define JSVAL_ERROR_COOKIE OBJECT_TO_JSVAL((JSObject*)0x10) |
96 |
|
97 |
/* Macros used by JS_DEFINE_CALLINFOn. */ |
98 |
#ifdef DEBUG |
99 |
#define _JS_CI_NAME(op) ,#op |
100 |
#else |
101 |
#define _JS_CI_NAME(op) |
102 |
#endif |
103 |
|
104 |
#define _JS_I32_ARGSIZE nanojit::ARGSIZE_LO |
105 |
#define _JS_I32_RETSIZE nanojit::ARGSIZE_LO |
106 |
#define _JS_F64_ARGSIZE nanojit::ARGSIZE_F |
107 |
#define _JS_F64_RETSIZE nanojit::ARGSIZE_F |
108 |
#define _JS_PTR_ARGSIZE nanojit::ARGSIZE_LO |
109 |
#if defined AVMPLUS_64BIT |
110 |
# define _JS_PTR_RETSIZE nanojit::ARGSIZE_Q |
111 |
#else |
112 |
# define _JS_PTR_RETSIZE nanojit::ARGSIZE_LO |
113 |
#endif |
114 |
|
115 |
/* |
116 |
* Supported types for builtin functions. |
117 |
* |
118 |
* Types with -- for the two string fields are not permitted as argument types |
119 |
* in JS_DEFINE_TRCINFO. |
120 |
* |
121 |
* There are three kinds of traceable-native error handling. |
122 |
* |
123 |
* - If a traceable native's return type ends with _FAIL, it always runs to |
124 |
* completion. It can either succeed or fail with an error or exception; |
125 |
* on success, it may or may not stay on trace. There may be side effects |
126 |
* in any case. If the call succeeds but bails off trace, we resume in the |
127 |
* interpreter at the next opcode. |
128 |
* |
129 |
* _FAIL builtins indicate failure or bailing off trace by setting bits in |
130 |
* cx->interpState->builtinStatus. |
131 |
* |
132 |
* - If a traceable native's return type contains _RETRY, it can either |
133 |
* succeed, fail with a JS exception, or tell the caller to bail off trace |
134 |
* and retry the call from the interpreter. The last case happens if the |
135 |
* builtin discovers that it can't do its job without examining the JS |
136 |
* stack, reentering the interpreter, accessing properties of the global |
137 |
* object, etc. |
138 |
* |
139 |
* The builtin must detect the need to retry before committing any side |
140 |
* effects. If a builtin can't do this, it must use a _FAIL return type |
141 |
* instead of _RETRY. |
142 |
* |
143 |
* _RETRY builtins indicate failure with a special return value that |
144 |
* depends on the return type: |
145 |
* |
146 |
* BOOL_RETRY: JSVAL_TO_BOOLEAN(JSVAL_VOID) |
147 |
* INT32_RETRY: any negative value |
148 |
* STRING_RETRY: NULL |
149 |
* OBJECT_RETRY_NULL: NULL |
150 |
* JSVAL_RETRY: JSVAL_ERROR_COOKIE |
151 |
* |
152 |
* _RETRY function calls are faster than _FAIL calls. Each _RETRY call |
153 |
* saves two writes to cx->bailExit and a read from state->builtinStatus. |
154 |
* |
155 |
* - All other traceable natives are infallible (e.g. Date.now, Math.log). |
156 |
* |
157 |
* Special builtins known to the tracer can have their own idiosyncratic |
158 |
* error codes. |
159 |
* |
160 |
* When a traceable native returns a value indicating failure, we fall off |
161 |
* trace. If an exception is pending, it is thrown; otherwise, we assume the |
162 |
* builtin had no side effects and retry the current bytecode in the |
163 |
* interpreter. |
164 |
* |
165 |
* So a builtin must not return a value indicating failure after causing side |
166 |
* effects (such as reporting an error), without setting an exception pending. |
167 |
* The operation would be retried, despite the first attempt's observable |
168 |
* effects. |
169 |
*/ |
170 |
#define _JS_CTYPE(ctype, size, pch, ach, flags) (ctype, size, pch, ach, flags) |
171 |
#define _JS_JSVAL_CTYPE(size, pch, ach, flags) (jsval, size, pch, ach, (flags | JSTN_UNBOX_AFTER)) |
172 |
|
173 |
#define _JS_CTYPE_CONTEXT _JS_CTYPE(JSContext *, _JS_PTR,"C", "", INFALLIBLE) |
174 |
#define _JS_CTYPE_RUNTIME _JS_CTYPE(JSRuntime *, _JS_PTR,"R", "", INFALLIBLE) |
175 |
#define _JS_CTYPE_THIS _JS_CTYPE(JSObject *, _JS_PTR,"T", "", INFALLIBLE) |
176 |
#define _JS_CTYPE_THIS_DOUBLE _JS_CTYPE(jsdouble, _JS_F64,"D", "", INFALLIBLE) |
177 |
#define _JS_CTYPE_THIS_STRING _JS_CTYPE(JSString *, _JS_PTR,"S", "", INFALLIBLE) |
178 |
#define _JS_CTYPE_CALLEE _JS_CTYPE(JSObject *, _JS_PTR,"f","", INFALLIBLE) |
179 |
#define _JS_CTYPE_CALLEE_PROTOTYPE _JS_CTYPE(JSObject *, _JS_PTR,"p","", INFALLIBLE) |
180 |
#define _JS_CTYPE_PC _JS_CTYPE(jsbytecode *, _JS_PTR,"P", "", INFALLIBLE) |
181 |
#define _JS_CTYPE_JSVALPTR _JS_CTYPE(jsval *, _JS_PTR,"P", "", INFALLIBLE) |
182 |
#define _JS_CTYPE_JSVAL _JS_JSVAL_CTYPE( _JS_PTR, "","v", INFALLIBLE) |
183 |
#define _JS_CTYPE_JSVAL_RETRY _JS_JSVAL_CTYPE( _JS_PTR, --, --, FAIL_COOKIE) |
184 |
#define _JS_CTYPE_JSVAL_FAIL _JS_JSVAL_CTYPE( _JS_PTR, --, --, FAIL_STATUS) |
185 |
#define _JS_CTYPE_BOOL _JS_CTYPE(JSBool, _JS_I32, "","i", INFALLIBLE) |
186 |
#define _JS_CTYPE_BOOL_RETRY _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_VOID) |
187 |
#define _JS_CTYPE_BOOL_FAIL _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_STATUS) |
188 |
#define _JS_CTYPE_INT32 _JS_CTYPE(int32, _JS_I32, "","i", INFALLIBLE) |
189 |
#define _JS_CTYPE_INT32_RETRY _JS_CTYPE(int32, _JS_I32, --, --, FAIL_NEG) |
190 |
#define _JS_CTYPE_INT32_FAIL _JS_CTYPE(int32, _JS_I32, --, --, FAIL_STATUS) |
191 |
#define _JS_CTYPE_UINT32 _JS_CTYPE(uint32, _JS_I32, "","i", INFALLIBLE) |
192 |
#define _JS_CTYPE_UINT32_RETRY _JS_CTYPE(uint32, _JS_I32, --, --, FAIL_NEG) |
193 |
#define _JS_CTYPE_UINT32_FAIL _JS_CTYPE(uint32, _JS_I32, --, --, FAIL_STATUS) |
194 |
#define _JS_CTYPE_DOUBLE _JS_CTYPE(jsdouble, _JS_F64, "","d", INFALLIBLE) |
195 |
#define _JS_CTYPE_DOUBLE_FAIL _JS_CTYPE(jsdouble, _JS_F64, --, --, FAIL_STATUS) |
196 |
#define _JS_CTYPE_STRING _JS_CTYPE(JSString *, _JS_PTR, "","s", INFALLIBLE) |
197 |
#define _JS_CTYPE_STRING_RETRY _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_NULL) |
198 |
#define _JS_CTYPE_STRING_FAIL _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_STATUS) |
199 |
#define _JS_CTYPE_OBJECT _JS_CTYPE(JSObject *, _JS_PTR, "","o", INFALLIBLE) |
200 |
#define _JS_CTYPE_OBJECT_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL) |
201 |
#define _JS_CTYPE_OBJECT_FAIL _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_STATUS) |
202 |
#define _JS_CTYPE_CONSTRUCTOR_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL | \ |
203 |
JSTN_CONSTRUCTOR) |
204 |
#define _JS_CTYPE_REGEXP _JS_CTYPE(JSObject *, _JS_PTR, "","r", INFALLIBLE) |
205 |
#define _JS_CTYPE_SCOPEPROP _JS_CTYPE(JSScopeProperty *, _JS_PTR, --, --, INFALLIBLE) |
206 |
#define _JS_CTYPE_SIDEEXIT _JS_CTYPE(SideExit *, _JS_PTR, --, --, INFALLIBLE) |
207 |
#define _JS_CTYPE_INTERPSTATE _JS_CTYPE(InterpState *, _JS_PTR, --, --, INFALLIBLE) |
208 |
#define _JS_CTYPE_FRAGMENT _JS_CTYPE(nanojit::Fragment *, _JS_PTR, --, --, INFALLIBLE) |
209 |
#define _JS_CTYPE_CLASS _JS_CTYPE(JSClass *, _JS_PTR, --, --, INFALLIBLE) |
210 |
#define _JS_CTYPE_DOUBLEPTR _JS_CTYPE(double *, _JS_PTR, --, --, INFALLIBLE) |
211 |
|
212 |
#define _JS_EXPAND(tokens) tokens |
213 |
|
214 |
#define _JS_CTYPE_TYPE2(t,s,p,a,f) t |
215 |
#define _JS_CTYPE_TYPE(tyname) _JS_EXPAND(_JS_CTYPE_TYPE2 _JS_CTYPE_##tyname) |
216 |
#define _JS_CTYPE_RETSIZE2(t,s,p,a,f) s##_RETSIZE |
217 |
#define _JS_CTYPE_RETSIZE(tyname) _JS_EXPAND(_JS_CTYPE_RETSIZE2 _JS_CTYPE_##tyname) |
218 |
#define _JS_CTYPE_ARGSIZE2(t,s,p,a,f) s##_ARGSIZE |
219 |
#define _JS_CTYPE_ARGSIZE(tyname) _JS_EXPAND(_JS_CTYPE_ARGSIZE2 _JS_CTYPE_##tyname) |
220 |
#define _JS_CTYPE_PCH2(t,s,p,a,f) p |
221 |
#define _JS_CTYPE_PCH(tyname) _JS_EXPAND(_JS_CTYPE_PCH2 _JS_CTYPE_##tyname) |
222 |
#define _JS_CTYPE_ACH2(t,s,p,a,f) a |
223 |
#define _JS_CTYPE_ACH(tyname) _JS_EXPAND(_JS_CTYPE_ACH2 _JS_CTYPE_##tyname) |
224 |
#define _JS_CTYPE_FLAGS2(t,s,p,a,f) f |
225 |
#define _JS_CTYPE_FLAGS(tyname) _JS_EXPAND(_JS_CTYPE_FLAGS2 _JS_CTYPE_##tyname) |
226 |
|
227 |
#define _JS_static_TN(t) static t |
228 |
#define _JS_static_CI static |
229 |
#define _JS_extern_TN(t) extern t |
230 |
#define _JS_extern_CI |
231 |
#define _JS_FRIEND_TN(t) extern JS_FRIEND_API(t) |
232 |
#define _JS_FRIEND_CI |
233 |
#define _JS_TN_LINKAGE(linkage, t) _JS_##linkage##_TN(t) |
234 |
#define _JS_CI_LINKAGE(linkage) _JS_##linkage##_CI |
235 |
|
236 |
#define _JS_CALLINFO(name) name##_ci |
237 |
|
238 |
#if defined(JS_NO_FASTCALL) && defined(NANOJIT_IA32) |
239 |
#define _JS_DEFINE_CALLINFO(linkage, name, crtype, cargtypes, argtypes, cse, fold) \ |
240 |
_JS_TN_LINKAGE(linkage, crtype) name cargtypes; \ |
241 |
_JS_CI_LINKAGE(linkage) const nanojit::CallInfo _JS_CALLINFO(name) = \ |
242 |
{ (intptr_t) &name, argtypes, cse, fold, nanojit::ABI_CDECL _JS_CI_NAME(name) }; |
243 |
#else |
244 |
#define _JS_DEFINE_CALLINFO(linkage, name, crtype, cargtypes, argtypes, cse, fold) \ |
245 |
_JS_TN_LINKAGE(linkage, crtype) FASTCALL name cargtypes; \ |
246 |
_JS_CI_LINKAGE(linkage) const nanojit::CallInfo _JS_CALLINFO(name) = \ |
247 |
{ (intptr_t) &name, argtypes, cse, fold, nanojit::ABI_FASTCALL _JS_CI_NAME(name) }; |
248 |
#endif |
249 |
|
250 |
/* |
251 |
* Declare a C function named <op> and a CallInfo struct named <op>_callinfo so the |
252 |
* tracer can call it. |linkage| controls the visibility of both the function |
253 |
* and the CallInfo global. It can be extern, static, or FRIEND, which |
254 |
* specifies JS_FRIEND_API linkage for the function. |
255 |
*/ |
256 |
#define JS_DEFINE_CALLINFO_1(linkage, rt, op, at0, cse, fold) \ |
257 |
_JS_DEFINE_CALLINFO(linkage, op, _JS_CTYPE_TYPE(rt), (_JS_CTYPE_TYPE(at0)), \ |
258 |
(_JS_CTYPE_ARGSIZE(at0) << 2) | _JS_CTYPE_RETSIZE(rt), cse, fold) |
259 |
#define JS_DEFINE_CALLINFO_2(linkage, rt, op, at0, at1, cse, fold) \ |
260 |
_JS_DEFINE_CALLINFO(linkage, op, _JS_CTYPE_TYPE(rt), \ |
261 |
(_JS_CTYPE_TYPE(at0), _JS_CTYPE_TYPE(at1)), \ |
262 |
(_JS_CTYPE_ARGSIZE(at0) << 4) | (_JS_CTYPE_ARGSIZE(at1) << 2) | \ |
263 |
_JS_CTYPE_RETSIZE(rt), \ |
264 |
cse, fold) |
265 |
#define JS_DEFINE_CALLINFO_3(linkage, rt, op, at0, at1, at2, cse, fold) \ |
266 |
_JS_DEFINE_CALLINFO(linkage, op, _JS_CTYPE_TYPE(rt), \ |
267 |
(_JS_CTYPE_TYPE(at0), _JS_CTYPE_TYPE(at1), _JS_CTYPE_TYPE(at2)), \ |
268 |
(_JS_CTYPE_ARGSIZE(at0) << 6) | (_JS_CTYPE_ARGSIZE(at1) << 4) | \ |
269 |
(_JS_CTYPE_ARGSIZE(at2) << 2) | _JS_CTYPE_RETSIZE(rt), \ |
270 |
cse, fold) |
271 |
#define JS_DEFINE_CALLINFO_4(linkage, rt, op, at0, at1, at2, at3, cse, fold) \ |
272 |
_JS_DEFINE_CALLINFO(linkage, op, _JS_CTYPE_TYPE(rt), \ |
273 |
(_JS_CTYPE_TYPE(at0), _JS_CTYPE_TYPE(at1), _JS_CTYPE_TYPE(at2), \ |
274 |
_JS_CTYPE_TYPE(at3)), \ |
275 |
(_JS_CTYPE_ARGSIZE(at0) << 8) | (_JS_CTYPE_ARGSIZE(at1) << 6) | \ |
276 |
(_JS_CTYPE_ARGSIZE(at2) << 4) | (_JS_CTYPE_ARGSIZE(at3) << 2) | \ |
277 |
_JS_CTYPE_RETSIZE(rt), \ |
278 |
cse, fold) |
279 |
#define JS_DEFINE_CALLINFO_5(linkage, rt, op, at0, at1, at2, at3, at4, cse, fold) \ |
280 |
_JS_DEFINE_CALLINFO(linkage, op, _JS_CTYPE_TYPE(rt), \ |
281 |
(_JS_CTYPE_TYPE(at0), _JS_CTYPE_TYPE(at1), _JS_CTYPE_TYPE(at2), \ |
282 |
_JS_CTYPE_TYPE(at3), _JS_CTYPE_TYPE(at4)), \ |
283 |
(_JS_CTYPE_ARGSIZE(at0) << 10) | (_JS_CTYPE_ARGSIZE(at1) << 8) | \ |
284 |
(_JS_CTYPE_ARGSIZE(at2) << 6) | (_JS_CTYPE_ARGSIZE(at3) << 4) | \ |
285 |
(_JS_CTYPE_ARGSIZE(at4) << 2) | _JS_CTYPE_RETSIZE(rt), \ |
286 |
cse, fold) |
287 |
|
288 |
#define JS_DEFINE_CALLINFO_6(linkage, rt, op, at0, at1, at2, at3, at4, at5, cse, fold) \ |
289 |
_JS_DEFINE_CALLINFO(linkage, op, _JS_CTYPE_TYPE(rt), \ |
290 |
(_JS_CTYPE_TYPE(at0), _JS_CTYPE_TYPE(at1), _JS_CTYPE_TYPE(at2), \ |
291 |
_JS_CTYPE_TYPE(at3), _JS_CTYPE_TYPE(at4), _JS_CTYPE_TYPE(at5)), \ |
292 |
(_JS_CTYPE_ARGSIZE(at0) << 12) | (_JS_CTYPE_ARGSIZE(at1) << 10) | \ |
293 |
(_JS_CTYPE_ARGSIZE(at2) << 8) | (_JS_CTYPE_ARGSIZE(at3) << 6) | \ |
294 |
(_JS_CTYPE_ARGSIZE(at4) << 4) | (_JS_CTYPE_ARGSIZE(at5) << 2) | \ |
295 |
_JS_CTYPE_RETSIZE(rt), cse, fold) |
296 |
|
297 |
#define JS_DECLARE_CALLINFO(name) extern const nanojit::CallInfo _JS_CALLINFO(name); |
298 |
|
299 |
#define _JS_TN_INIT_HELPER_n(n, args) _JS_TN_INIT_HELPER_##n args |
300 |
|
301 |
#define _JS_TN_INIT_HELPER_1(linkage, rt, op, at0, cse, fold) \ |
302 |
&_JS_CALLINFO(op), \ |
303 |
_JS_CTYPE_PCH(at0), \ |
304 |
_JS_CTYPE_ACH(at0), \ |
305 |
_JS_CTYPE_FLAGS(rt) |
306 |
|
307 |
#define _JS_TN_INIT_HELPER_2(linkage, rt, op, at0, at1, cse, fold) \ |
308 |
&_JS_CALLINFO(op), \ |
309 |
_JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ |
310 |
_JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ |
311 |
_JS_CTYPE_FLAGS(rt) |
312 |
|
313 |
#define _JS_TN_INIT_HELPER_3(linkage, rt, op, at0, at1, at2, cse, fold) \ |
314 |
&_JS_CALLINFO(op), \ |
315 |
_JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ |
316 |
_JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ |
317 |
_JS_CTYPE_FLAGS(rt) |
318 |
|
319 |
#define _JS_TN_INIT_HELPER_4(linkage, rt, op, at0, at1, at2, at3, cse, fold) \ |
320 |
&_JS_CALLINFO(op), \ |
321 |
_JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ |
322 |
_JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ |
323 |
_JS_CTYPE_FLAGS(rt) |
324 |
|
325 |
#define _JS_TN_INIT_HELPER_5(linkage, rt, op, at0, at1, at2, at3, at4, cse, fold) \ |
326 |
&_JS_CALLINFO(op), \ |
327 |
_JS_CTYPE_PCH(at4) _JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) \ |
328 |
_JS_CTYPE_PCH(at0), \ |
329 |
_JS_CTYPE_ACH(at4) _JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) \ |
330 |
_JS_CTYPE_ACH(at0), \ |
331 |
_JS_CTYPE_FLAGS(rt) |
332 |
|
333 |
#define _JS_TN_INIT_HELPER_6(linkage, rt, op, at0, at1, at2, at3, at4, at5, cse, fold) \ |
334 |
&_JS_CALLINFO(op), \ |
335 |
_JS_CTYPE_PCH(at5) _JS_CTYPE_PCH(at4) _JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) \ |
336 |
_JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ |
337 |
_JS_CTYPE_ACH(at5) _JS_CTYPE_ACH(at4) _JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) \ |
338 |
_JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ |
339 |
_JS_CTYPE_FLAGS(rt) |
340 |
|
341 |
#define JS_DEFINE_TRCINFO_1(name, tn0) \ |
342 |
_JS_DEFINE_CALLINFO_n tn0 \ |
343 |
JSTraceableNative name##_trcinfo[] = { \ |
344 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn0 } \ |
345 |
}; |
346 |
|
347 |
#define JS_DEFINE_TRCINFO_2(name, tn0, tn1) \ |
348 |
_JS_DEFINE_CALLINFO_n tn0 \ |
349 |
_JS_DEFINE_CALLINFO_n tn1 \ |
350 |
JSTraceableNative name##_trcinfo[] = { \ |
351 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \ |
352 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn1 } \ |
353 |
}; |
354 |
|
355 |
#define JS_DEFINE_TRCINFO_3(name, tn0, tn1, tn2) \ |
356 |
_JS_DEFINE_CALLINFO_n tn0 \ |
357 |
_JS_DEFINE_CALLINFO_n tn1 \ |
358 |
_JS_DEFINE_CALLINFO_n tn2 \ |
359 |
JSTraceableNative name##_trcinfo[] = { \ |
360 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \ |
361 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn1 | JSTN_MORE }, \ |
362 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn2 } \ |
363 |
}; |
364 |
|
365 |
#define JS_DEFINE_TRCINFO_4(name, tn0, tn1, tn2, tn3) \ |
366 |
_JS_DEFINE_CALLINFO_n tn0 \ |
367 |
_JS_DEFINE_CALLINFO_n tn1 \ |
368 |
_JS_DEFINE_CALLINFO_n tn2 \ |
369 |
_JS_DEFINE_CALLINFO_n tn3 \ |
370 |
JSTraceableNative name##_trcinfo[] = { \ |
371 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \ |
372 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn1 | JSTN_MORE }, \ |
373 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn2 | JSTN_MORE }, \ |
374 |
{ (JSFastNative)name, _JS_TN_INIT_HELPER_n tn3 } \ |
375 |
}; |
376 |
|
377 |
#define _JS_DEFINE_CALLINFO_n(n, args) JS_DEFINE_CALLINFO_##n args |
378 |
|
379 |
jsdouble FASTCALL |
380 |
js_StringToNumber(JSContext* cx, JSString* str); |
381 |
|
382 |
jsdouble FASTCALL |
383 |
js_BooleanOrUndefinedToNumber(JSContext* cx, int32 unboxed); |
384 |
|
385 |
static JS_INLINE JSBool |
386 |
js_Int32ToId(JSContext* cx, int32 index, jsid* id) |
387 |
{ |
388 |
if (index <= JSVAL_INT_MAX) { |
389 |
*id = INT_TO_JSID(index); |
390 |
return JS_TRUE; |
391 |
} |
392 |
JSString* str = js_NumberToString(cx, index); |
393 |
if (!str) |
394 |
return JS_FALSE; |
395 |
return js_ValueToStringId(cx, STRING_TO_JSVAL(str), id); |
396 |
} |
397 |
|
398 |
/* Extern version of js_SetBuiltinError. */ |
399 |
extern JS_FRIEND_API(void) |
400 |
js_SetTraceableNativeFailed(JSContext *cx); |
401 |
|
402 |
#else |
403 |
|
404 |
#define JS_DEFINE_CALLINFO_1(linkage, rt, op, at0, cse, fold) |
405 |
#define JS_DEFINE_CALLINFO_2(linkage, rt, op, at0, at1, cse, fold) |
406 |
#define JS_DEFINE_CALLINFO_3(linkage, rt, op, at0, at1, at2, cse, fold) |
407 |
#define JS_DEFINE_CALLINFO_4(linkage, rt, op, at0, at1, at2, at3, cse, fold) |
408 |
#define JS_DEFINE_CALLINFO_5(linkage, rt, op, at0, at1, at2, at3, at4, cse, fold) |
409 |
#define JS_DECLARE_CALLINFO(name) |
410 |
#define JS_DEFINE_TRCINFO_1(name, tn0) |
411 |
#define JS_DEFINE_TRCINFO_2(name, tn0, tn1) |
412 |
#define JS_DEFINE_TRCINFO_3(name, tn0, tn1, tn2) |
413 |
#define JS_DEFINE_TRCINFO_4(name, tn0, tn1, tn2, tn3) |
414 |
|
415 |
#endif /* !JS_TRACER */ |
416 |
|
417 |
/* Defined in jsobj.cpp. */ |
418 |
JS_DECLARE_CALLINFO(js_Object_tn) |
419 |
JS_DECLARE_CALLINFO(js_NewInstance) |
420 |
|
421 |
/* Defined in jsarray.cpp. */ |
422 |
JS_DECLARE_CALLINFO(js_Array_dense_setelem) |
423 |
JS_DECLARE_CALLINFO(js_NewEmptyArray) |
424 |
JS_DECLARE_CALLINFO(js_NewUninitializedArray) |
425 |
JS_DECLARE_CALLINFO(js_ArrayCompPush) |
426 |
|
427 |
/* Defined in jsnum.cpp. */ |
428 |
JS_DECLARE_CALLINFO(js_NumberToString) |
429 |
|
430 |
/* Defined in jsstr.cpp. */ |
431 |
JS_DECLARE_CALLINFO(js_String_tn) |
432 |
JS_DECLARE_CALLINFO(js_CompareStrings) |
433 |
JS_DECLARE_CALLINFO(js_ConcatStrings) |
434 |
JS_DECLARE_CALLINFO(js_EqualStrings) |
435 |
JS_DECLARE_CALLINFO(js_String_getelem) |
436 |
JS_DECLARE_CALLINFO(js_String_p_charCodeAt) |
437 |
JS_DECLARE_CALLINFO(js_String_p_charCodeAt0) |
438 |
JS_DECLARE_CALLINFO(js_String_p_charCodeAt0_int) |
439 |
JS_DECLARE_CALLINFO(js_String_p_charCodeAt_int) |
440 |
|
441 |
/* Defined in jsbuiltins.cpp. */ |
442 |
#define BUILTIN1(linkage, rt, op, at0, cse, fold) JS_DECLARE_CALLINFO(op) |
443 |
#define BUILTIN2(linkage, rt, op, at0, at1, cse, fold) JS_DECLARE_CALLINFO(op) |
444 |
#define BUILTIN3(linkage, rt, op, at0, at1, at2, cse, fold) JS_DECLARE_CALLINFO(op) |
445 |
#define BUILTIN4(linkage, rt, op, at0, at1, at2, at3, cse, fold) JS_DECLARE_CALLINFO(op) |
446 |
#define BUILTIN5(linkage, rt, op, at0, at1, at2, at3, at4, cse, fold) JS_DECLARE_CALLINFO(op) |
447 |
#include "builtins.tbl" |
448 |
#undef BUILTIN |
449 |
#undef BUILTIN1 |
450 |
#undef BUILTIN2 |
451 |
#undef BUILTIN3 |
452 |
#undef BUILTIN4 |
453 |
#undef BUILTIN5 |
454 |
|
455 |
#endif /* jsbuiltins_h___ */ |