/[jscoverage]/trunk/js/jsbuiltins.cpp
ViewVC logotype

Annotation of /trunk/js/jsbuiltins.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 460 - (hide annotations)
Sat Sep 26 23:15:22 2009 UTC (11 years ago) by siliconforks
File size: 12133 byte(s)
Upgrade to SpiderMonkey from Firefox 3.5.3.

1 siliconforks 399 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; -*-
2 siliconforks 332 * 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     * Andreas Gal <gal@mozilla.com>
22     *
23     * Contributor(s):
24     * Brendan Eich <brendan@mozilla.org>
25     * Mike Shaver <shaver@mozilla.org>
26     * David Anderson <danderson@mozilla.com>
27     *
28     * Alternatively, the contents of this file may be used under the terms of
29     * either of the GNU General Public License Version 2 or later (the "GPL"),
30     * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31     * in which case the provisions of the GPL or the LGPL are applicable instead
32     * of those above. If you wish to allow use of your version of this file only
33     * under the terms of either the GPL or the LGPL, and not to allow others to
34     * use your version of this file under the terms of the MPL, indicate your
35     * decision by deleting the provisions above and replace them with the notice
36     * and other provisions required by the GPL or the LGPL. If you do not delete
37     * the provisions above, a recipient may use your version of this file under
38     * the terms of any one of the MPL, the GPL or the LGPL.
39     *
40     * ***** END LICENSE BLOCK ***** */
41    
42     #include "jsstddef.h"
43     #include <math.h>
44    
45     #include "jsapi.h"
46     #include "jsarray.h"
47     #include "jsbool.h"
48     #include "jscntxt.h"
49     #include "jsgc.h"
50     #include "jsiter.h"
51     #include "jslibmath.h"
52     #include "jsmath.h"
53     #include "jsnum.h"
54     #include "prmjtime.h"
55 siliconforks 399 #include "jsdate.h"
56 siliconforks 332 #include "jsscope.h"
57     #include "jsstr.h"
58 siliconforks 399 #include "jsbuiltins.h"
59 siliconforks 332 #include "jstracer.h"
60    
61     using namespace avmplus;
62     using namespace nanojit;
63    
64 siliconforks 399 extern jsdouble js_NaN;
65    
66 siliconforks 460 JS_FRIEND_API(void)
67     js_SetTraceableNativeFailed(JSContext *cx)
68     {
69     js_SetBuiltinError(cx);
70     }
71    
72 siliconforks 332 /*
73     * NB: bool FASTCALL is not compatible with Nanojit's calling convention usage.
74     * Do not use bool FASTCALL, use JSBool only!
75     */
76    
77     jsdouble FASTCALL
78     js_dmod(jsdouble a, jsdouble b)
79     {
80     if (b == 0.0) {
81     jsdpun u;
82     u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK;
83     u.s.lo = 0xffffffff;
84     return u.d;
85     }
86     jsdouble r;
87     #ifdef XP_WIN
88     /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
89     if (JSDOUBLE_IS_FINITE(a) && JSDOUBLE_IS_INFINITE(b))
90     r = a;
91     else
92     #endif
93     r = fmod(a, b);
94     return r;
95     }
96    
97 siliconforks 399 int32 FASTCALL
98     js_imod(int32 a, int32 b)
99 siliconforks 332 {
100     if (a < 0 || b <= 0)
101     return -1;
102     int r = a % b;
103     return r;
104     }
105    
106     /* The following boxing/unboxing primitives we can't emit inline because
107     they either interact with the GC and depend on Spidermonkey's 32-bit
108     integer representation. */
109    
110     jsval FASTCALL
111     js_BoxDouble(JSContext* cx, jsdouble d)
112     {
113 siliconforks 399 int32 i;
114     if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i))
115 siliconforks 332 return INT_TO_JSVAL(i);
116     JS_ASSERT(JS_ON_TRACE(cx));
117     jsval v; /* not rooted but ok here because we know GC won't run */
118     if (!js_NewDoubleInRootedValue(cx, d, &v))
119     return JSVAL_ERROR_COOKIE;
120     return v;
121     }
122    
123     jsval FASTCALL
124 siliconforks 399 js_BoxInt32(JSContext* cx, int32 i)
125 siliconforks 332 {
126     if (JS_LIKELY(INT_FITS_IN_JSVAL(i)))
127     return INT_TO_JSVAL(i);
128     JS_ASSERT(JS_ON_TRACE(cx));
129     jsval v; /* not rooted but ok here because we know GC won't run */
130     jsdouble d = (jsdouble)i;
131     if (!js_NewDoubleInRootedValue(cx, d, &v))
132     return JSVAL_ERROR_COOKIE;
133     return v;
134     }
135    
136     jsdouble FASTCALL
137     js_UnboxDouble(jsval v)
138     {
139     if (JS_LIKELY(JSVAL_IS_INT(v)))
140     return (jsdouble)JSVAL_TO_INT(v);
141     return *JSVAL_TO_DOUBLE(v);
142     }
143    
144 siliconforks 399 int32 FASTCALL
145 siliconforks 332 js_UnboxInt32(jsval v)
146     {
147     if (JS_LIKELY(JSVAL_IS_INT(v)))
148     return JSVAL_TO_INT(v);
149     return js_DoubleToECMAInt32(*JSVAL_TO_DOUBLE(v));
150     }
151    
152     int32 FASTCALL
153     js_DoubleToInt32(jsdouble d)
154     {
155     return js_DoubleToECMAInt32(d);
156     }
157    
158 siliconforks 399 uint32 FASTCALL
159 siliconforks 332 js_DoubleToUint32(jsdouble d)
160     {
161     return js_DoubleToECMAUint32(d);
162     }
163    
164     jsdouble FASTCALL
165     js_StringToNumber(JSContext* cx, JSString* str)
166     {
167     const jschar* bp;
168     const jschar* end;
169     const jschar* ep;
170     jsdouble d;
171    
172     JSSTRING_CHARS_AND_END(str, bp, end);
173     if ((!js_strtod(cx, bp, end, &ep, &d) ||
174     js_SkipWhiteSpace(ep, end) != end) &&
175     (!js_strtointeger(cx, bp, end, &ep, 0, &d) ||
176     js_SkipWhiteSpace(ep, end) != end)) {
177     return js_NaN;
178     }
179     return d;
180     }
181    
182 siliconforks 399 int32 FASTCALL
183 siliconforks 332 js_StringToInt32(JSContext* cx, JSString* str)
184     {
185     const jschar* bp;
186     const jschar* end;
187     const jschar* ep;
188     jsdouble d;
189    
190     JSSTRING_CHARS_AND_END(str, bp, end);
191 siliconforks 460 if ((!js_strtod(cx, bp, end, &ep, &d) ||
192     js_SkipWhiteSpace(ep, end) != end) &&
193     (!js_strtointeger(cx, bp, end, &ep, 0, &d) ||
194     js_SkipWhiteSpace(ep, end) != end)) {
195 siliconforks 332 return 0;
196 siliconforks 460 }
197 siliconforks 399 return js_DoubleToECMAInt32(d);
198 siliconforks 332 }
199    
200 siliconforks 399 SideExit* FASTCALL
201 siliconforks 332 js_CallTree(InterpState* state, Fragment* f)
202     {
203     union { NIns *code; GuardRecord* (FASTCALL *func)(InterpState*, Fragment*); } u;
204    
205     u.code = f->code();
206     JS_ASSERT(u.code);
207    
208 siliconforks 399 GuardRecord* rec;
209 siliconforks 332 #if defined(JS_NO_FASTCALL) && defined(NANOJIT_IA32)
210 siliconforks 399 SIMULATE_FASTCALL(rec, state, NULL, u.func);
211 siliconforks 332 #else
212 siliconforks 399 rec = u.func(state, NULL);
213 siliconforks 332 #endif
214 siliconforks 399 VMSideExit* lr = (VMSideExit*)rec->exit;
215 siliconforks 332
216 siliconforks 399 if (lr->exitType == NESTED_EXIT) {
217 siliconforks 332 /* This only occurs once a tree call guard mismatches and we unwind the tree call stack.
218     We store the first (innermost) tree call guard in state and we will try to grow
219     the outer tree the failing call was in starting at that guard. */
220 siliconforks 399 if (!state->lastTreeCallGuard) {
221 siliconforks 332 state->lastTreeCallGuard = lr;
222 siliconforks 460 FrameInfo** rp = (FrameInfo**)state->rp;
223 siliconforks 399 state->rpAtLastTreeCall = rp + lr->calldepth;
224     }
225 siliconforks 332 } else {
226     /* If the tree exits on a regular (non-nested) guard, keep updating lastTreeExitGuard
227     with that guard. If we mismatch on a tree call guard, this will contain the last
228     non-nested guard we encountered, which is the innermost loop or branch guard. */
229     state->lastTreeExitGuard = lr;
230     }
231    
232     return lr;
233     }
234    
235     JSBool FASTCALL
236     js_AddProperty(JSContext* cx, JSObject* obj, JSScopeProperty* sprop)
237     {
238     JS_ASSERT(OBJ_IS_NATIVE(obj));
239     JS_ASSERT(SPROP_HAS_STUB_SETTER(sprop));
240    
241     JS_LOCK_OBJ(cx, obj);
242 siliconforks 460
243 siliconforks 332 JSScope* scope = OBJ_SCOPE(obj);
244 siliconforks 460 uint32 slot;
245 siliconforks 332 if (scope->object == obj) {
246     JS_ASSERT(!SCOPE_HAS_PROPERTY(scope, sprop));
247     } else {
248     scope = js_GetMutableScope(cx, obj);
249 siliconforks 460 if (!scope)
250     goto exit_trace;
251 siliconforks 332 }
252    
253 siliconforks 460 slot = sprop->slot;
254     if (!scope->table && sprop->parent == scope->lastProp && slot == scope->freeslot) {
255 siliconforks 332 if (slot < STOBJ_NSLOTS(obj) && !OBJ_GET_CLASS(cx, obj)->reserveSlots) {
256 siliconforks 460 JS_ASSERT(JSVAL_IS_VOID(STOBJ_GET_SLOT(obj, scope->freeslot)));
257     ++scope->freeslot;
258 siliconforks 332 } else {
259 siliconforks 460 if (!js_AllocSlot(cx, obj, &slot))
260     goto exit_trace;
261    
262     if (slot != sprop->slot) {
263     js_FreeSlot(cx, obj, slot);
264     goto exit_trace;
265 siliconforks 332 }
266     }
267    
268 siliconforks 460 js_ExtendScopeShape(cx, scope, sprop);
269 siliconforks 332 ++scope->entryCount;
270     scope->lastProp = sprop;
271 siliconforks 460 } else {
272     JSScopeProperty *sprop2 = js_AddScopeProperty(cx, scope, sprop->id,
273     sprop->getter,
274     sprop->setter,
275     SPROP_INVALID_SLOT,
276     sprop->attrs,
277     sprop->flags,
278     sprop->shortid);
279     if (sprop2 != sprop)
280     goto exit_trace;
281 siliconforks 332 }
282    
283 siliconforks 460 if (js_IsPropertyCacheDisabled(cx))
284     goto exit_trace;
285 siliconforks 332
286     JS_UNLOCK_SCOPE(cx, scope);
287 siliconforks 460 return JS_TRUE;
288    
289     exit_trace:
290     JS_UNLOCK_SCOPE(cx, scope);
291 siliconforks 332 return JS_FALSE;
292     }
293    
294 siliconforks 460 static JSBool
295     HasProperty(JSContext* cx, JSObject* obj, jsid id)
296 siliconforks 332 {
297 siliconforks 460 // Check that we know how the lookup op will behave.
298     for (JSObject* pobj = obj; pobj; pobj = OBJ_GET_PROTO(cx, pobj)) {
299     if (pobj->map->ops->lookupProperty != js_LookupProperty)
300     return JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID);
301     JSClass* clasp = OBJ_GET_CLASS(cx, pobj);
302     if (clasp->resolve != JS_ResolveStub && clasp != &js_StringClass)
303     return JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID);
304     }
305 siliconforks 332
306     JSObject* obj2;
307     JSProperty* prop;
308 siliconforks 460 if (!js_LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop))
309     return JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID);
310 siliconforks 332 if (prop)
311     OBJ_DROP_PROPERTY(cx, obj2, prop);
312     return prop != NULL;
313     }
314    
315 siliconforks 399 JSBool FASTCALL
316 siliconforks 460 js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr)
317     {
318     jsid id;
319     if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id))
320     return JSVAL_TO_BOOLEAN(JSVAL_VOID);
321    
322     return HasProperty(cx, obj, id);
323     }
324    
325     JSBool FASTCALL
326 siliconforks 399 js_HasNamedPropertyInt32(JSContext* cx, JSObject* obj, int32 index)
327     {
328     jsid id;
329 siliconforks 460 if (!js_Int32ToId(cx, index, &id))
330 siliconforks 399 return JSVAL_TO_BOOLEAN(JSVAL_VOID);
331    
332 siliconforks 460 return HasProperty(cx, obj, id);
333 siliconforks 399 }
334    
335 siliconforks 332 jsval FASTCALL
336     js_CallGetter(JSContext* cx, JSObject* obj, JSScopeProperty* sprop)
337     {
338     JS_ASSERT(!SPROP_HAS_STUB_GETTER(sprop));
339     jsval v;
340 siliconforks 460 if (!js_GetSprop(cx, sprop, obj, &v))
341 siliconforks 332 return JSVAL_ERROR_COOKIE;
342     return v;
343     }
344    
345     JSString* FASTCALL
346     js_TypeOfObject(JSContext* cx, JSObject* obj)
347     {
348     JSType type = JS_TypeOfValue(cx, OBJECT_TO_JSVAL(obj));
349     return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
350     }
351    
352     JSString* FASTCALL
353 siliconforks 399 js_TypeOfBoolean(JSContext* cx, int32 unboxed)
354 siliconforks 332 {
355 siliconforks 460 /* Watch out for pseudo-booleans. */
356     jsval boxed = PSEUDO_BOOLEAN_TO_JSVAL(unboxed);
357 siliconforks 332 JS_ASSERT(JSVAL_IS_VOID(boxed) || JSVAL_IS_BOOLEAN(boxed));
358     JSType type = JS_TypeOfValue(cx, boxed);
359     return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
360     }
361    
362     jsdouble FASTCALL
363 siliconforks 399 js_BooleanOrUndefinedToNumber(JSContext* cx, int32 unboxed)
364 siliconforks 332 {
365 siliconforks 460 if (unboxed == JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID))
366 siliconforks 332 return js_NaN;
367 siliconforks 460 JS_ASSERT(unboxed == JS_TRUE || unboxed == JS_FALSE);
368 siliconforks 332 return unboxed;
369     }
370    
371     JSString* FASTCALL
372 siliconforks 399 js_BooleanOrUndefinedToString(JSContext *cx, int32 unboxed)
373     {
374     JS_ASSERT(uint32(unboxed) <= 2);
375     return ATOM_TO_STRING(cx->runtime->atomState.booleanAtoms[unboxed]);
376     }
377    
378 siliconforks 460 JSObject* FASTCALL
379     js_Arguments(JSContext* cx)
380 siliconforks 332 {
381 siliconforks 460 return NULL;
382 siliconforks 332 }
383    
384     JSObject* FASTCALL
385 siliconforks 460 js_NewNullClosure(JSContext* cx, JSObject* funobj, JSObject* proto, JSObject* parent)
386 siliconforks 332 {
387 siliconforks 460 JS_ASSERT(HAS_FUNCTION_CLASS(funobj));
388     JS_ASSERT(HAS_FUNCTION_CLASS(proto));
389     JS_ASSERT(JS_ON_TRACE(cx));
390    
391     JSFunction *fun = (JSFunction*) funobj;
392     JS_ASSERT(GET_FUNCTION_PRIVATE(cx, funobj) == fun);
393    
394     JSObject* closure = (JSObject*) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
395     if (!closure)
396     return NULL;
397    
398     js_HoldScope(OBJ_SCOPE(proto));
399     closure->map = proto->map;
400     closure->classword = jsuword(&js_FunctionClass);
401     closure->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
402     closure->fslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent);
403     closure->fslots[JSSLOT_PRIVATE] = PRIVATE_TO_JSVAL(fun);
404     for (unsigned i = JSSLOT_PRIVATE + 1; i != JS_INITIAL_NSLOTS; ++i)
405     closure->fslots[i] = JSVAL_VOID;
406     closure->dslots = NULL;
407     return closure;
408 siliconforks 332 }
409    
410 siliconforks 399 #define BUILTIN1 JS_DEFINE_CALLINFO_1
411     #define BUILTIN2 JS_DEFINE_CALLINFO_2
412     #define BUILTIN3 JS_DEFINE_CALLINFO_3
413     #define BUILTIN4 JS_DEFINE_CALLINFO_4
414     #define BUILTIN5 JS_DEFINE_CALLINFO_5
415 siliconforks 332 #include "builtins.tbl"

  ViewVC Help
Powered by ViewVC 1.1.24