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

Annotation of /trunk/js/jsbuiltins.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 332 - (hide annotations)
Thu Oct 23 19:03:33 2008 UTC (11 years, 11 months ago) by siliconforks
File size: 26154 byte(s)
Add SpiderMonkey from Firefox 3.1b1.

The following directories and files were removed:
correct/, correct.js
liveconnect/
nanojit/
t/
v8/
vprof/
xpconnect/
all JavaScript files (Y.js, call.js, if.js, math-partial-sums.js, md5.js, perfect.js, trace-test.js, trace.js)


1 siliconforks 332 /* -*- 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     * 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     #include "jsscope.h"
56     #include "jsstr.h"
57     #include "jstracer.h"
58    
59     #include "nanojit/avmplus.h"
60     #include "nanojit/nanojit.h"
61    
62     using namespace avmplus;
63     using namespace nanojit;
64    
65     /*
66     * NB: bool FASTCALL is not compatible with Nanojit's calling convention usage.
67     * Do not use bool FASTCALL, use JSBool only!
68     */
69    
70     jsdouble FASTCALL
71     js_dmod(jsdouble a, jsdouble b)
72     {
73     if (b == 0.0) {
74     jsdpun u;
75     u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK;
76     u.s.lo = 0xffffffff;
77     return u.d;
78     }
79     jsdouble r;
80     #ifdef XP_WIN
81     /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
82     if (JSDOUBLE_IS_FINITE(a) && JSDOUBLE_IS_INFINITE(b))
83     r = a;
84     else
85     #endif
86     r = fmod(a, b);
87     return r;
88     }
89    
90     jsint FASTCALL
91     js_imod(jsint a, jsint b)
92     {
93     if (a < 0 || b <= 0)
94     return -1;
95     int r = a % b;
96     return r;
97     }
98    
99     /* The following boxing/unboxing primitives we can't emit inline because
100     they either interact with the GC and depend on Spidermonkey's 32-bit
101     integer representation. */
102    
103     jsval FASTCALL
104     js_BoxDouble(JSContext* cx, jsdouble d)
105     {
106     jsint i;
107     if (JSDOUBLE_IS_INT(d, i))
108     return INT_TO_JSVAL(i);
109     JS_ASSERT(JS_ON_TRACE(cx));
110     jsval v; /* not rooted but ok here because we know GC won't run */
111     if (!js_NewDoubleInRootedValue(cx, d, &v))
112     return JSVAL_ERROR_COOKIE;
113     return v;
114     }
115    
116     jsval FASTCALL
117     js_BoxInt32(JSContext* cx, jsint i)
118     {
119     if (JS_LIKELY(INT_FITS_IN_JSVAL(i)))
120     return INT_TO_JSVAL(i);
121     JS_ASSERT(JS_ON_TRACE(cx));
122     jsval v; /* not rooted but ok here because we know GC won't run */
123     jsdouble d = (jsdouble)i;
124     if (!js_NewDoubleInRootedValue(cx, d, &v))
125     return JSVAL_ERROR_COOKIE;
126     return v;
127     }
128    
129     jsdouble FASTCALL
130     js_UnboxDouble(jsval v)
131     {
132     if (JS_LIKELY(JSVAL_IS_INT(v)))
133     return (jsdouble)JSVAL_TO_INT(v);
134     return *JSVAL_TO_DOUBLE(v);
135     }
136    
137     jsint FASTCALL
138     js_UnboxInt32(jsval v)
139     {
140     if (JS_LIKELY(JSVAL_IS_INT(v)))
141     return JSVAL_TO_INT(v);
142     return js_DoubleToECMAInt32(*JSVAL_TO_DOUBLE(v));
143     }
144    
145     int32 FASTCALL
146     js_DoubleToInt32(jsdouble d)
147     {
148     return js_DoubleToECMAInt32(d);
149     }
150    
151     int32 FASTCALL
152     js_DoubleToUint32(jsdouble d)
153     {
154     return js_DoubleToECMAUint32(d);
155     }
156    
157     jsdouble FASTCALL
158     js_Math_sin(jsdouble d)
159     {
160     return sin(d);
161     }
162    
163     jsdouble FASTCALL
164     js_Math_cos(jsdouble d)
165     {
166     return cos(d);
167     }
168    
169     jsdouble FASTCALL
170     js_Math_floor(jsdouble d)
171     {
172     return floor(d);
173     }
174    
175     jsdouble FASTCALL
176     js_Math_ceil(jsdouble d)
177     {
178     return ceil(d);
179     }
180    
181     extern jsdouble js_NaN;
182    
183     jsdouble FASTCALL
184     js_Math_pow(jsdouble d, jsdouble p)
185     {
186     if (!JSDOUBLE_IS_FINITE(p) && (d == 1.0 || d == -1.0))
187     return js_NaN;
188     if (p == 0)
189     return 1.0;
190     return pow(d, p);
191     }
192    
193     jsdouble FASTCALL
194     js_Math_sqrt(jsdouble d)
195     {
196     return sqrt(d);
197     }
198    
199     jsdouble FASTCALL
200     js_Math_log(jsdouble d)
201     {
202     #if !JS_USE_FDLIBM_MATH && defined(SOLARIS) && defined(__GNUC__)
203     if (d < 0)
204     return js_NaN;
205     #endif
206     return log(d);
207     }
208    
209     jsdouble FASTCALL
210     js_Math_max(jsdouble d, jsdouble p)
211     {
212     if (JSDOUBLE_IS_NaN(d) || JSDOUBLE_IS_NaN(p))
213     return js_NaN;
214    
215     if (p == 0 && p == d && fd_copysign(1.0, d) == -1)
216     return p;
217     return (d > p) ? d : p;
218     }
219    
220     JSBool FASTCALL
221     js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
222     {
223     JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
224    
225     jsuint length = ARRAY_DENSE_LENGTH(obj);
226     if ((jsuint)i < length) {
227     if (obj->dslots[i] == JSVAL_HOLE) {
228     if (i >= obj->fslots[JSSLOT_ARRAY_LENGTH])
229     obj->fslots[JSSLOT_ARRAY_LENGTH] = i + 1;
230     obj->fslots[JSSLOT_ARRAY_COUNT]++;
231     }
232     obj->dslots[i] = v;
233     return JS_TRUE;
234     }
235     return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSID(i), &v);
236     }
237    
238     JSString* FASTCALL
239     js_Array_p_join(JSContext* cx, JSObject* obj, JSString *str)
240     {
241     jsval v;
242     if (!js_array_join_sub(cx, obj, TO_STRING, str, &v))
243     return NULL;
244     JS_ASSERT(JSVAL_IS_STRING(v));
245     return JSVAL_TO_STRING(v);
246     }
247    
248     jsval FASTCALL
249     js_Array_p_push1(JSContext* cx, JSObject* obj, jsval v)
250     {
251     if (!(OBJ_IS_DENSE_ARRAY(cx, obj)
252     ? js_array_push1_dense(cx, obj, v, &v)
253     : js_array_push_slowly(cx, obj, 1, &v, &v))) {
254     return JSVAL_ERROR_COOKIE;
255     }
256     return v;
257     }
258    
259     jsval FASTCALL
260     js_Array_p_pop(JSContext* cx, JSObject* obj)
261     {
262     jsval v;
263     if (!(OBJ_IS_DENSE_ARRAY(cx, obj)
264     ? js_array_pop_dense(cx, obj, &v)
265     : js_array_pop_slowly(cx, obj, &v))) {
266     return JSVAL_ERROR_COOKIE;
267     }
268     return v;
269     }
270    
271     JSString* FASTCALL
272     js_String_p_substring(JSContext* cx, JSString* str, jsint begin, jsint end)
273     {
274     JS_ASSERT(end >= begin);
275     JS_ASSERT(JS_ON_TRACE(cx));
276     return js_NewDependentString(cx, str, (size_t)begin, (size_t)(end - begin));
277     }
278    
279     JSString* FASTCALL
280     js_String_p_substring_1(JSContext* cx, JSString* str, jsint begin)
281     {
282     jsint end = JSSTRING_LENGTH(str);
283     JS_ASSERT(end >= begin);
284     JS_ASSERT(JS_ON_TRACE(cx));
285     return js_NewDependentString(cx, str, (size_t)begin, (size_t)(end - begin));
286     }
287    
288     JSString* FASTCALL
289     js_String_getelem(JSContext* cx, JSString* str, jsint i)
290     {
291     if ((size_t)i >= JSSTRING_LENGTH(str))
292     return NULL;
293     return js_GetUnitString(cx, str, (size_t)i);
294     }
295    
296     JSString* FASTCALL
297     js_String_fromCharCode(JSContext* cx, jsint i)
298     {
299     JS_ASSERT(JS_ON_TRACE(cx));
300     jschar c = (jschar)i;
301     if (c < UNIT_STRING_LIMIT)
302     return js_GetUnitStringForChar(cx, c);
303     return js_NewStringCopyN(cx, &c, 1);
304     }
305    
306     jsint FASTCALL
307     js_String_p_charCodeAt(JSString* str, jsint i)
308     {
309     if (i < 0 || (jsint)JSSTRING_LENGTH(str) <= i)
310     return -1;
311     return JSSTRING_CHARS(str)[i];
312     }
313    
314     jsdouble FASTCALL
315     js_Math_random(JSRuntime* rt)
316     {
317     JS_LOCK_RUNTIME(rt);
318     js_random_init(rt);
319     jsdouble z = js_random_nextDouble(rt);
320     JS_UNLOCK_RUNTIME(rt);
321     return z;
322     }
323    
324     JSString* FASTCALL
325     js_String_p_concat_1int(JSContext* cx, JSString* str, jsint i)
326     {
327     // FIXME: should be able to use stack buffer and avoid istr...
328     JSString* istr = js_NumberToString(cx, i);
329     if (!istr)
330     return NULL;
331     return js_ConcatStrings(cx, str, istr);
332     }
333    
334     JSString* FASTCALL
335     js_String_p_concat_2str(JSContext* cx, JSString* str, JSString* a, JSString* b)
336     {
337     str = js_ConcatStrings(cx, str, a);
338     if (str)
339     return js_ConcatStrings(cx, str, b);
340     return NULL;
341     }
342    
343     JSString* FASTCALL
344     js_String_p_concat_3str(JSContext* cx, JSString* str, JSString* a, JSString* b, JSString* c)
345     {
346     str = js_ConcatStrings(cx, str, a);
347     if (str) {
348     str = js_ConcatStrings(cx, str, b);
349     if (str)
350     return js_ConcatStrings(cx, str, c);
351     }
352     return NULL;
353     }
354    
355     JSObject* FASTCALL
356     js_String_p_match(JSContext* cx, JSString* str, jsbytecode *pc, JSObject* regexp)
357     {
358     jsval vp[3] = { JSVAL_NULL, STRING_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) };
359     if (!js_StringMatchHelper(cx, 1, vp, pc))
360     return (JSObject*) JSVAL_TO_BOOLEAN(JSVAL_VOID);
361     JS_ASSERT(JSVAL_IS_NULL(vp[0]) ||
362     (!JSVAL_IS_PRIMITIVE(vp[0]) && OBJ_IS_ARRAY(cx, JSVAL_TO_OBJECT(vp[0]))));
363     return JSVAL_TO_OBJECT(vp[0]);
364     }
365    
366     JSObject* FASTCALL
367     js_String_p_match_obj(JSContext* cx, JSObject* str, jsbytecode *pc, JSObject* regexp)
368     {
369     jsval vp[3] = { JSVAL_NULL, OBJECT_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) };
370     if (!js_StringMatchHelper(cx, 1, vp, pc))
371     return (JSObject*) JSVAL_TO_BOOLEAN(JSVAL_VOID);
372     JS_ASSERT(JSVAL_IS_NULL(vp[0]) ||
373     (!JSVAL_IS_PRIMITIVE(vp[0]) && OBJ_IS_ARRAY(cx, JSVAL_TO_OBJECT(vp[0]))));
374     return JSVAL_TO_OBJECT(vp[0]);
375     }
376    
377     JSString* FASTCALL
378     js_String_p_replace_str(JSContext* cx, JSString* str, JSObject* regexp, JSString* repstr)
379     {
380     jsval vp[4] = {
381     JSVAL_NULL, STRING_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp), STRING_TO_JSVAL(repstr)
382     };
383     if (!js_StringReplaceHelper(cx, 2, NULL, repstr, vp))
384     return NULL;
385     JS_ASSERT(JSVAL_IS_STRING(vp[0]));
386     return JSVAL_TO_STRING(vp[0]);
387     }
388    
389     JSString* FASTCALL
390     js_String_p_replace_str2(JSContext* cx, JSString* str, JSString* patstr, JSString* repstr)
391     {
392     jsval vp[4] = {
393     JSVAL_NULL, STRING_TO_JSVAL(str), STRING_TO_JSVAL(patstr), STRING_TO_JSVAL(repstr)
394     };
395     if (!js_StringReplaceHelper(cx, 2, NULL, repstr, vp))
396     return NULL;
397     JS_ASSERT(JSVAL_IS_STRING(vp[0]));
398     return JSVAL_TO_STRING(vp[0]);
399     }
400    
401     JSString* FASTCALL
402     js_String_p_replace_str3(JSContext* cx, JSString* str, JSString* patstr, JSString* repstr,
403     JSString* flagstr)
404     {
405     jsval vp[5] = {
406     JSVAL_NULL, STRING_TO_JSVAL(str), STRING_TO_JSVAL(patstr), STRING_TO_JSVAL(repstr),
407     STRING_TO_JSVAL(flagstr)
408     };
409     if (!js_StringReplaceHelper(cx, 3, NULL, repstr, vp))
410     return NULL;
411     JS_ASSERT(JSVAL_IS_STRING(vp[0]));
412     return JSVAL_TO_STRING(vp[0]);
413     }
414    
415     JSObject* FASTCALL
416     js_String_p_split(JSContext* cx, JSString* str, JSString* sepstr)
417     {
418     // FIXME: optimize by calling into a lower level exported from jsstr.cpp.
419     jsval vp[4] = { JSVAL_NULL, STRING_TO_JSVAL(str), STRING_TO_JSVAL(sepstr), JSVAL_VOID };
420     if (!js_str_split(cx, 2, vp))
421     return NULL;
422     JS_ASSERT(JSVAL_IS_OBJECT(vp[0]));
423     return JSVAL_TO_OBJECT(vp[0]);
424     }
425    
426     jsdouble FASTCALL
427     js_StringToNumber(JSContext* cx, JSString* str)
428     {
429     const jschar* bp;
430     const jschar* end;
431     const jschar* ep;
432     jsdouble d;
433    
434     JSSTRING_CHARS_AND_END(str, bp, end);
435     if ((!js_strtod(cx, bp, end, &ep, &d) ||
436     js_SkipWhiteSpace(ep, end) != end) &&
437     (!js_strtointeger(cx, bp, end, &ep, 0, &d) ||
438     js_SkipWhiteSpace(ep, end) != end)) {
439     return js_NaN;
440     }
441     return d;
442     }
443    
444     jsint FASTCALL
445     js_StringToInt32(JSContext* cx, JSString* str)
446     {
447     const jschar* bp;
448     const jschar* end;
449     const jschar* ep;
450     jsdouble d;
451    
452     JSSTRING_CHARS_AND_END(str, bp, end);
453     if (!js_strtod(cx, bp, end, &ep, &d) || js_SkipWhiteSpace(ep, end) != end)
454     return 0;
455     return (jsint)d;
456     }
457    
458     jsdouble FASTCALL
459     js_ParseFloat(JSContext* cx, JSString* str)
460     {
461     const jschar* bp;
462     const jschar* end;
463     const jschar* ep;
464     jsdouble d;
465    
466     JSSTRING_CHARS_AND_END(str, bp, end);
467     if (!js_strtod(cx, bp, end, &ep, &d) || ep == bp)
468     return js_NaN;
469     return d;
470     }
471    
472     jsdouble FASTCALL
473     js_ParseInt(JSContext* cx, JSString* str)
474     {
475     const jschar* bp;
476     const jschar* end;
477     const jschar* ep;
478     jsdouble d;
479    
480     JSSTRING_CHARS_AND_END(str, bp, end);
481     if (!js_strtointeger(cx, bp, end, &ep, 0, &d) || ep == bp)
482     return js_NaN;
483     return d;
484     }
485    
486     jsdouble FASTCALL
487     js_ParseIntDouble(jsdouble d)
488     {
489     if (!JSDOUBLE_IS_FINITE(d))
490     return js_NaN;
491     return floor(d);
492     }
493    
494     jsval FASTCALL
495     js_Any_getprop(JSContext* cx, JSObject* obj, JSString* idstr)
496     {
497     jsval v;
498     jsid id;
499    
500     if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id))
501     return JSVAL_ERROR_COOKIE;
502     if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
503     return JSVAL_ERROR_COOKIE;
504     return v;
505     }
506    
507     JSBool FASTCALL
508     js_Any_setprop(JSContext* cx, JSObject* obj, JSString* idstr, jsval v)
509     {
510     jsid id;
511     if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id))
512     return JS_FALSE;
513     return OBJ_SET_PROPERTY(cx, obj, id, &v);
514     }
515    
516     jsval FASTCALL
517     js_Any_getelem(JSContext* cx, JSObject* obj, jsint index)
518     {
519     jsval v;
520     jsid id;
521     if (index < 0)
522     return JSVAL_ERROR_COOKIE;
523     if (!js_IndexToId(cx, index, &id))
524     return JSVAL_ERROR_COOKIE;
525     if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
526     return JSVAL_ERROR_COOKIE;
527     return v;
528     }
529    
530     JSBool FASTCALL
531     js_Any_setelem(JSContext* cx, JSObject* obj, jsint index, jsval v)
532     {
533     jsid id;
534     if (index < 0)
535     return JSVAL_ERROR_COOKIE;
536     if (!js_IndexToId(cx, index, &id))
537     return JS_FALSE;
538     return OBJ_SET_PROPERTY(cx, obj, id, &v);
539     }
540    
541     JSObject* FASTCALL
542     js_FastValueToIterator(JSContext* cx, jsuint flags, jsval v)
543     {
544     if (!js_ValueToIterator(cx, flags, &v))
545     return NULL;
546     return JSVAL_TO_OBJECT(v);
547     }
548    
549     jsval FASTCALL
550     js_FastCallIteratorNext(JSContext* cx, JSObject* iterobj)
551     {
552     jsval v;
553     if (!js_CallIteratorNext(cx, iterobj, &v))
554     return JSVAL_ERROR_COOKIE;
555     return v;
556     }
557    
558     GuardRecord* FASTCALL
559     js_CallTree(InterpState* state, Fragment* f)
560     {
561     GuardRecord* lr;
562     union { NIns *code; GuardRecord* (FASTCALL *func)(InterpState*, Fragment*); } u;
563    
564     u.code = f->code();
565     JS_ASSERT(u.code);
566    
567     #if defined(JS_NO_FASTCALL) && defined(NANOJIT_IA32)
568     SIMULATE_FASTCALL(lr, state, NULL, u.func);
569     #else
570     lr = u.func(state, NULL);
571     #endif
572    
573     if (lr->exit->exitType == NESTED_EXIT) {
574     /* This only occurs once a tree call guard mismatches and we unwind the tree call stack.
575     We store the first (innermost) tree call guard in state and we will try to grow
576     the outer tree the failing call was in starting at that guard. */
577     if (!state->lastTreeCallGuard)
578     state->lastTreeCallGuard = lr;
579     } else {
580     /* If the tree exits on a regular (non-nested) guard, keep updating lastTreeExitGuard
581     with that guard. If we mismatch on a tree call guard, this will contain the last
582     non-nested guard we encountered, which is the innermost loop or branch guard. */
583     state->lastTreeExitGuard = lr;
584     }
585    
586     return lr;
587     }
588    
589     JS_STATIC_ASSERT(JSSLOT_PRIVATE == JSSLOT_ARRAY_LENGTH);
590     JS_STATIC_ASSERT(JSSLOT_ARRAY_LENGTH + 1 == JSSLOT_ARRAY_COUNT);
591    
592     JSObject* FASTCALL
593     js_FastNewArray(JSContext* cx, JSObject* proto)
594     {
595     JS_ASSERT(OBJ_IS_ARRAY(cx, proto));
596    
597     JS_ASSERT(JS_ON_TRACE(cx));
598     JSObject* obj = (JSObject*) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
599     if (!obj)
600     return NULL;
601    
602     JSClass* clasp = &js_ArrayClass;
603     obj->classword = jsuword(clasp);
604    
605     obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
606     obj->fslots[JSSLOT_PARENT] = proto->fslots[JSSLOT_PARENT];
607    
608     obj->fslots[JSSLOT_ARRAY_LENGTH] = 0;
609     obj->fslots[JSSLOT_ARRAY_COUNT] = 0;
610     for (unsigned i = JSSLOT_ARRAY_COUNT + 1; i != JS_INITIAL_NSLOTS; ++i)
611     obj->fslots[i] = JSVAL_VOID;
612    
613     JSObjectOps* ops = clasp->getObjectOps(cx, clasp);
614     obj->map = ops->newObjectMap(cx, 1, ops, clasp, obj);
615     if (!obj->map)
616     return NULL;
617     obj->dslots = NULL;
618     return obj;
619     }
620    
621     JSObject* FASTCALL
622     js_FastNewObject(JSContext* cx, JSObject* ctor)
623     {
624     JS_ASSERT(HAS_FUNCTION_CLASS(ctor));
625     JSFunction* fun = GET_FUNCTION_PRIVATE(cx, ctor);
626     JSClass* clasp = FUN_INTERPRETED(fun) ? &js_ObjectClass : fun->u.n.clasp;
627     JS_ASSERT(clasp != &js_ArrayClass);
628    
629     JS_LOCK_OBJ(cx, ctor);
630     JSScope *scope = OBJ_SCOPE(ctor);
631     JS_ASSERT(scope->object == ctor);
632     JSAtom* atom = cx->runtime->atomState.classPrototypeAtom;
633    
634     JSScopeProperty *sprop = SCOPE_GET_PROPERTY(scope, ATOM_TO_JSID(atom));
635     JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, scope));
636     jsval v = LOCKED_OBJ_GET_SLOT(ctor, sprop->slot);
637     JS_UNLOCK_SCOPE(cx, scope);
638    
639     JSObject* proto;
640     if (JSVAL_IS_PRIMITIVE(v)) {
641     if (!js_GetClassPrototype(cx, JSVAL_TO_OBJECT(ctor->fslots[JSSLOT_PARENT]),
642     INT_TO_JSID(JSProto_Object), &proto)) {
643     return NULL;
644     }
645     } else {
646     proto = JSVAL_TO_OBJECT(v);
647     }
648    
649     JS_ASSERT(JS_ON_TRACE(cx));
650     JSObject* obj = (JSObject*) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
651     if (!obj)
652     return NULL;
653    
654     obj->classword = jsuword(clasp);
655     obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
656     obj->fslots[JSSLOT_PARENT] = ctor->fslots[JSSLOT_PARENT];
657     for (unsigned i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i)
658     obj->fslots[i] = JSVAL_VOID;
659    
660     obj->map = js_HoldObjectMap(cx, proto->map);
661     obj->dslots = NULL;
662     return obj;
663     }
664    
665     JSBool FASTCALL
666     js_AddProperty(JSContext* cx, JSObject* obj, JSScopeProperty* sprop)
667     {
668     JSScopeProperty* sprop2 = NULL; // initialize early to make MSVC happy
669    
670     JS_ASSERT(OBJ_IS_NATIVE(obj));
671     JS_ASSERT(SPROP_HAS_STUB_SETTER(sprop));
672    
673     JS_LOCK_OBJ(cx, obj);
674     JSScope* scope = OBJ_SCOPE(obj);
675     if (scope->object == obj) {
676     JS_ASSERT(!SCOPE_HAS_PROPERTY(scope, sprop));
677     } else {
678     scope = js_GetMutableScope(cx, obj);
679     if (!scope) {
680     JS_UNLOCK_OBJ(cx, obj);
681     return JS_FALSE;
682     }
683     }
684    
685     uint32 slot = sprop->slot;
686     if (!scope->table && sprop->parent == scope->lastProp && slot == scope->map.freeslot) {
687     if (slot < STOBJ_NSLOTS(obj) && !OBJ_GET_CLASS(cx, obj)->reserveSlots) {
688     JS_ASSERT(JSVAL_IS_VOID(STOBJ_GET_SLOT(obj, scope->map.freeslot)));
689     ++scope->map.freeslot;
690     } else {
691     if (!js_AllocSlot(cx, obj, &slot)) {
692     JS_UNLOCK_SCOPE(cx, scope);
693     return JS_FALSE;
694     }
695    
696     if (slot != sprop->slot)
697     goto slot_changed;
698     }
699    
700     SCOPE_EXTEND_SHAPE(cx, scope, sprop);
701     ++scope->entryCount;
702     scope->lastProp = sprop;
703     JS_UNLOCK_SCOPE(cx, scope);
704     return JS_TRUE;
705     }
706    
707     sprop2 = js_AddScopeProperty(cx, scope, sprop->id,
708     sprop->getter, sprop->setter, SPROP_INVALID_SLOT,
709     sprop->attrs, sprop->flags, sprop->shortid);
710     if (sprop2 == sprop) {
711     JS_UNLOCK_SCOPE(cx, scope);
712     return JS_TRUE;
713     }
714     slot = sprop2->slot;
715    
716     slot_changed:
717     js_FreeSlot(cx, obj, slot);
718     JS_UNLOCK_SCOPE(cx, scope);
719     return JS_FALSE;
720     }
721    
722     JSBool FASTCALL
723     js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr)
724     {
725     jsid id;
726     if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id))
727     return JS_FALSE;
728    
729     JSObject* obj2;
730     JSProperty* prop;
731     if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
732     return JSVAL_TO_BOOLEAN(JSVAL_VOID);
733     if (prop)
734     OBJ_DROP_PROPERTY(cx, obj2, prop);
735     return prop != NULL;
736     }
737    
738     jsval FASTCALL
739     js_CallGetter(JSContext* cx, JSObject* obj, JSScopeProperty* sprop)
740     {
741     JS_ASSERT(!SPROP_HAS_STUB_GETTER(sprop));
742     jsval v;
743     if (!SPROP_GET(cx, sprop, obj, obj, &v))
744     return JSVAL_ERROR_COOKIE;
745     return v;
746     }
747    
748     JSString* FASTCALL
749     js_TypeOfObject(JSContext* cx, JSObject* obj)
750     {
751     JSType type = JS_TypeOfValue(cx, OBJECT_TO_JSVAL(obj));
752     return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
753     }
754    
755     JSString* FASTCALL
756     js_TypeOfBoolean(JSContext* cx, jsint unboxed)
757     {
758     jsval boxed = BOOLEAN_TO_JSVAL(unboxed);
759     JS_ASSERT(JSVAL_IS_VOID(boxed) || JSVAL_IS_BOOLEAN(boxed));
760     JSType type = JS_TypeOfValue(cx, boxed);
761     return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
762     }
763    
764     jsint FASTCALL
765     js_Object_p_hasOwnProperty(JSContext* cx, JSObject* obj, JSString *str)
766     {
767     jsid id = ATOM_TO_JSID(STRING_TO_JSVAL(str));
768     jsval v;
769     if (!js_HasOwnProperty(cx, obj->map->ops->lookupProperty, obj, id, &v))
770     return JSVAL_TO_BOOLEAN(JSVAL_VOID);
771     JS_ASSERT(JSVAL_IS_BOOLEAN(v));
772     return JSVAL_TO_BOOLEAN(v);
773     }
774    
775     jsint FASTCALL
776     js_Object_p_propertyIsEnumerable(JSContext* cx, JSObject* obj, JSString *str)
777     {
778     jsid id = ATOM_TO_JSID(STRING_TO_JSVAL(str));
779     jsval v;
780     if (!js_PropertyIsEnumerable(cx, obj, id, &v))
781     return JSVAL_TO_BOOLEAN(JSVAL_VOID);
782     JS_ASSERT(JSVAL_IS_BOOLEAN(v));
783     return JSVAL_TO_BOOLEAN(v);
784     }
785    
786     jsdouble FASTCALL
787     js_BooleanToNumber(JSContext* cx, jsint unboxed)
788     {
789     if (unboxed == JSVAL_TO_BOOLEAN(JSVAL_VOID))
790     return js_NaN;
791     return unboxed;
792     }
793    
794     JSString* FASTCALL
795     js_ObjectToString(JSContext* cx, JSObject* obj)
796     {
797     if (!obj)
798     return ATOM_TO_STRING(cx->runtime->atomState.nullAtom);
799     jsval v;
800     if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_STRING, &v))
801     return NULL;
802     JS_ASSERT(JSVAL_IS_STRING(v));
803     return JSVAL_TO_STRING(v);
804     }
805    
806     JSObject* FASTCALL
807     js_Array_1int(JSContext* cx, JSObject* proto, jsint i)
808     {
809     JS_ASSERT(JS_ON_TRACE(cx));
810     JSObject* obj = js_FastNewArray(cx, proto);
811     if (obj)
812     obj->fslots[JSSLOT_ARRAY_LENGTH] = i;
813     return obj;
814     }
815    
816     #define ARRAY_CTOR_GUTS(exact_len, newslots_code) \
817     JS_ASSERT(JS_ON_TRACE(cx)); \
818     JSObject* obj = js_FastNewArray(cx, proto); \
819     if (obj) { \
820     const uint32 len = ARRAY_GROWBY; \
821     jsval* newslots = (jsval*) JS_malloc(cx, sizeof (jsval) * (len + 1)); \
822     if (newslots) { \
823     obj->dslots = newslots + 1; \
824     ARRAY_SET_DENSE_LENGTH(obj, len); \
825     {newslots_code} \
826     while (++newslots < obj->dslots + len) \
827     *newslots = JSVAL_HOLE; \
828     obj->fslots[JSSLOT_ARRAY_LENGTH] = (exact_len); \
829     return obj; \
830     } \
831     } \
832     return NULL;
833    
834     JSObject* FASTCALL
835     js_Array_1str(JSContext* cx, JSObject* proto, JSString *str)
836     {
837     ARRAY_CTOR_GUTS(1, *++newslots = STRING_TO_JSVAL(str);)
838     }
839    
840     JSObject* FASTCALL
841     js_Array_2obj(JSContext* cx, JSObject* proto, JSObject *obj1, JSObject* obj2)
842     {
843     ARRAY_CTOR_GUTS(2,
844     *++newslots = OBJECT_TO_JSVAL(obj1);
845     *++newslots = OBJECT_TO_JSVAL(obj2);)
846     }
847    
848     JSObject* FASTCALL
849     js_Array_3num(JSContext* cx, JSObject* proto, jsdouble n1, jsdouble n2, jsdouble n3)
850     {
851     ARRAY_CTOR_GUTS(3,
852     if (!js_NewDoubleInRootedValue(cx, n1, ++newslots))
853     return NULL;
854     if (!js_NewDoubleInRootedValue(cx, n2, ++newslots))
855     return NULL;
856     if (!js_NewDoubleInRootedValue(cx, n3, ++newslots))
857     return NULL;)
858     }
859    
860     JSObject* FASTCALL
861     js_Arguments(JSContext* cx)
862     {
863     return NULL;
864     }
865    
866     jsdouble FASTCALL
867     js_Date_now(JSContext*)
868     {
869     return PRMJ_Now() / PRMJ_USEC_PER_MSEC;
870     }
871    
872     /* soft float */
873    
874     jsdouble FASTCALL
875     js_fneg(jsdouble x)
876     {
877     return -x;
878     }
879    
880     jsdouble FASTCALL
881     js_i2f(jsint i)
882     {
883     return i;
884     }
885    
886     jsdouble FASTCALL
887     js_u2f(jsuint u)
888     {
889     return u;
890     }
891    
892     jsint FASTCALL
893     js_fcmpeq(jsdouble x, jsdouble y)
894     {
895     return x==y;
896     }
897    
898     jsint FASTCALL
899     js_fcmplt(jsdouble x, jsdouble y)
900     {
901     return x < y;
902     }
903    
904     jsint FASTCALL
905     js_fcmple(jsdouble x, jsdouble y)
906     {
907     return x <= y;
908     }
909    
910     jsint FASTCALL
911     js_fcmpgt(jsdouble x, jsdouble y)
912     {
913     return x > y;
914     }
915    
916     jsint FASTCALL
917     js_fcmpge(jsdouble x, jsdouble y)
918     {
919     return x >= y;
920     }
921    
922     jsdouble FASTCALL
923     js_fmul(jsdouble x, jsdouble y)
924     {
925     return x * y;
926     }
927     jsdouble FASTCALL
928     js_fadd(jsdouble x, jsdouble y)
929     {
930     return x + y;
931     }
932    
933     jsdouble FASTCALL
934     js_fdiv(jsdouble x, jsdouble y)
935     {
936     return x / y;
937     }
938    
939     jsdouble FASTCALL
940     js_fsub(jsdouble x, jsdouble y)
941     {
942     return x - y;
943     }
944    
945     #define LO ARGSIZE_LO
946     #define F ARGSIZE_F
947     #define Q ARGSIZE_Q
948    
949     #if defined AVMPLUS_64BIT
950     #define P ARGSIZE_Q
951     #else
952     #define P ARGSIZE_LO
953     #endif
954    
955     #ifdef DEBUG
956     #define NAME(op) ,#op
957     #else
958     #define NAME(op)
959     #endif
960    
961     #define BUILTIN1(op, at0, atr, tr, t0, cse, fold) \
962     { (intptr_t)&js_##op, (at0 << 2) | atr, cse, fold NAME(op) },
963     #define BUILTIN2(op, at0, at1, atr, tr, t0, t1, cse, fold) \
964     { (intptr_t)&js_##op, (at0 << 4) | (at1 << 2) | atr, cse, fold NAME(op) },
965     #define BUILTIN3(op, at0, at1, at2, atr, tr, t0, t1, t2, cse, fold) \
966     { (intptr_t)&js_##op, (at0 << 6) | (at1 << 4) | (at2 << 2) | atr, cse, fold NAME(op) },
967     #define BUILTIN4(op, at0, at1, at2, at3, atr, tr, t0, t1, t2, t3, cse, fold) \
968     { (intptr_t)&js_##op, (at0 << 8) | (at1 << 6) | (at2 << 4) | (at3 << 2) | atr, cse, fold NAME(op) },
969     #define BUILTIN5(op, at0, at1, at2, at3, at4, atr, tr, t0, t1, t2, t3, t4, cse, fold) \
970     { (intptr_t)&js_##op, (at0 << 10) | (at1 << 8) | (at2 << 6) | (at3 << 4) | (at4 << 2) | atr, cse, fold NAME(op) },
971    
972     struct CallInfo builtins[] = {
973     #include "builtins.tbl"
974     };

  ViewVC Help
Powered by ViewVC 1.1.24