mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Use explicit local roots in native methods (313763, r/sr=igor/shaver).
This commit is contained in:
parent
46120f51a9
commit
46a92c27aa
106
js/src/jsarray.c
106
js/src/jsarray.c
@ -1060,7 +1060,7 @@ array_shift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsuint length, i;
|
||||
jsid id, id2;
|
||||
jsval v, junk;
|
||||
jsval junk;
|
||||
|
||||
if (!js_GetLengthProperty(cx, obj, &length))
|
||||
return JS_FALSE;
|
||||
@ -1081,9 +1081,9 @@ array_shift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
return JS_FALSE;
|
||||
if (!IndexToId(cx, i - 1, &id2))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &argv[0]))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
|
||||
if (!OBJ_SET_PROPERTY(cx, obj, id2, &argv[0]))
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
@ -1102,7 +1102,7 @@ array_unshift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsuint length, last;
|
||||
uintN i;
|
||||
jsid id, id2;
|
||||
jsval v;
|
||||
jsval *vp, junk;
|
||||
|
||||
if (!js_GetLengthProperty(cx, obj, &length))
|
||||
return JS_FALSE;
|
||||
@ -1110,18 +1110,19 @@ array_unshift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
/* Slide up the array to make room for argc at the bottom. */
|
||||
if (length > 0) {
|
||||
last = length;
|
||||
vp = argv + argc;
|
||||
while (last--) {
|
||||
if (!IndexToExistingId(cx, obj, last, &id))
|
||||
return JS_FALSE;
|
||||
if (id == JSID_HOLE) {
|
||||
OBJ_DELETE_PROPERTY(cx, obj, id2, &v); /* v is junk. */
|
||||
OBJ_DELETE_PROPERTY(cx, obj, id2, &junk);
|
||||
continue;
|
||||
}
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
|
||||
return JS_FALSE;
|
||||
if (!IndexToId(cx, last + argc, &id2))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
|
||||
if (!OBJ_SET_PROPERTY(cx, obj, id2, vp))
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
@ -1145,16 +1146,20 @@ array_unshift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
static JSBool
|
||||
array_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsval *vp, junk;
|
||||
jsuint length, begin, end, count, delta, last;
|
||||
uintN i;
|
||||
jsdouble d;
|
||||
jsid id, id2;
|
||||
jsval v;
|
||||
JSObject *obj2;
|
||||
uintN i;
|
||||
|
||||
/* Nothing to do if no args. Otherwise lock and load length. */
|
||||
/*
|
||||
* Nothing to do if no args. Otherwise point vp at our one explicit local
|
||||
* root and get length.
|
||||
*/
|
||||
if (argc == 0)
|
||||
return JS_TRUE;
|
||||
vp = argv + argc;
|
||||
if (!js_GetLengthProperty(cx, obj, &length))
|
||||
return JS_FALSE;
|
||||
|
||||
@ -1228,11 +1233,11 @@ array_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
return JS_FALSE;
|
||||
if (id == JSID_HOLE)
|
||||
continue; /* don't fill holes in the new array */
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
|
||||
return JS_FALSE;
|
||||
if (!IndexToId(cx, last - begin, &id2))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_SET_PROPERTY(cx, obj2, id2, &v))
|
||||
if (!OBJ_SET_PROPERTY(cx, obj2, id2, vp))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
@ -1253,12 +1258,12 @@ array_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
if (!IndexToId(cx, last + delta, &id2))
|
||||
return JS_FALSE;
|
||||
if (id != JSID_HOLE) {
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
|
||||
if (!OBJ_SET_PROPERTY(cx, obj, id2, vp))
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &v))
|
||||
if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &junk))
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
@ -1271,12 +1276,12 @@ array_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
if (!IndexToId(cx, last - delta, &id2))
|
||||
return JS_FALSE;
|
||||
if (id != JSID_HOLE) {
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
|
||||
if (!OBJ_SET_PROPERTY(cx, obj, id2, vp))
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &v))
|
||||
if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &junk))
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
@ -1303,12 +1308,15 @@ array_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
static JSBool
|
||||
array_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsval *vp, v;
|
||||
JSObject *nobj, *aobj;
|
||||
jsuint length, alength, slot;
|
||||
uintN i;
|
||||
jsval v;
|
||||
jsid id, id2;
|
||||
|
||||
/* Hoist the explicit local root address computation. */
|
||||
vp = argv + argc;
|
||||
|
||||
/* Treat obj as the first argument; see ECMA 15.4.4.4. */
|
||||
--argv;
|
||||
JS_ASSERT(obj == JSVAL_TO_OBJECT(argv[0]));
|
||||
@ -1329,10 +1337,10 @@ array_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
if (!OBJ_GET_PROPERTY(cx, aobj,
|
||||
ATOM_TO_JSID(cx->runtime->atomState
|
||||
.lengthAtom),
|
||||
&v)) {
|
||||
vp)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (!ValueIsLength(cx, v, &alength))
|
||||
if (!ValueIsLength(cx, *vp, &alength))
|
||||
return JS_FALSE;
|
||||
for (slot = 0; slot < alength; slot++) {
|
||||
if (!IndexToExistingId(cx, aobj, slot, &id))
|
||||
@ -1344,11 +1352,11 @@ array_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (!OBJ_GET_PROPERTY(cx, aobj, id, &v))
|
||||
if (!OBJ_GET_PROPERTY(cx, aobj, id, vp))
|
||||
return JS_FALSE;
|
||||
if (!IndexToId(cx, length + slot, &id2))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v))
|
||||
if (!OBJ_SET_PROPERTY(cx, nobj, id2, vp))
|
||||
return JS_FALSE;
|
||||
}
|
||||
length += alength;
|
||||
@ -1356,9 +1364,10 @@ array_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
}
|
||||
}
|
||||
|
||||
*vp = v;
|
||||
if (!IndexToId(cx, length, &id))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_SET_PROPERTY(cx, nobj, id, &v))
|
||||
if (!OBJ_SET_PROPERTY(cx, nobj, id, vp))
|
||||
return JS_FALSE;
|
||||
length++;
|
||||
}
|
||||
@ -1369,11 +1378,14 @@ array_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
static JSBool
|
||||
array_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsval *vp;
|
||||
JSObject *nobj;
|
||||
jsuint length, begin, end, slot;
|
||||
jsdouble d;
|
||||
jsid id, id2;
|
||||
jsval v;
|
||||
|
||||
/* Hoist the explicit local root address computation. */
|
||||
vp = argv + argc;
|
||||
|
||||
/* Create a new Array object and store it in the rval local root. */
|
||||
nobj = js_NewArrayObject(cx, 0, NULL);
|
||||
@ -1422,11 +1434,11 @@ array_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
return JS_FALSE;
|
||||
if (id == JSID_HOLE)
|
||||
continue;
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
|
||||
return JS_FALSE;
|
||||
if (!IndexToId(cx, slot - begin, &id2))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v))
|
||||
if (!OBJ_SET_PROPERTY(cx, nobj, id2, vp))
|
||||
return JS_FALSE;
|
||||
}
|
||||
return js_SetLengthProperty(cx, nobj, end - begin);
|
||||
@ -1523,13 +1535,16 @@ static JSBool
|
||||
array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval,
|
||||
ArrayExtraMode mode)
|
||||
{
|
||||
jsval *vp, *sp, *origsp, *oldsp;
|
||||
jsuint length, newlen, i;
|
||||
JSObject *callable, *thisp, *newarr;
|
||||
jsval *sp, *origsp, *oldsp;
|
||||
void *mark;
|
||||
JSStackFrame *fp;
|
||||
JSBool ok, b;
|
||||
|
||||
/* Hoist the explicit local root address computation. */
|
||||
vp = argv + argc;
|
||||
|
||||
if (!js_GetLengthProperty(cx, obj, &length))
|
||||
return JS_FALSE;
|
||||
|
||||
@ -1545,6 +1560,11 @@ array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval,
|
||||
* Set our initial return condition, used for zero-length array cases
|
||||
* (and pre-size our map return to match our known length, for all cases).
|
||||
*/
|
||||
#ifdef __GNUC__ /* quell GCC overwarning */
|
||||
newlen = 0;
|
||||
newarr = NULL;
|
||||
ok = JS_TRUE;
|
||||
#endif
|
||||
switch (mode) {
|
||||
case MAP:
|
||||
case FILTER:
|
||||
@ -1589,14 +1609,14 @@ array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval,
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
jsid id;
|
||||
jsval v, rval2;
|
||||
jsval rval2;
|
||||
|
||||
ok = IndexToExistingId(cx, obj, i, &id);
|
||||
if (!ok)
|
||||
break;
|
||||
if (id == JSID_HOLE)
|
||||
continue;
|
||||
ok = OBJ_GET_PROPERTY(cx, obj, id, &v);
|
||||
ok = OBJ_GET_PROPERTY(cx, obj, id, vp);
|
||||
if (!ok)
|
||||
break;
|
||||
|
||||
@ -1604,7 +1624,7 @@ array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval,
|
||||
sp = origsp;
|
||||
*sp++ = OBJECT_TO_JSVAL(callable);
|
||||
*sp++ = OBJECT_TO_JSVAL(thisp);
|
||||
*sp++ = v;
|
||||
*sp++ = *vp;
|
||||
*sp++ = INT_TO_JSVAL(i);
|
||||
*sp++ = OBJECT_TO_JSVAL(obj);
|
||||
|
||||
@ -1639,11 +1659,11 @@ array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval,
|
||||
case FILTER:
|
||||
if (!b)
|
||||
break;
|
||||
/* Filter passed v, push as result. */
|
||||
/* Filter passed *vp, push as result. */
|
||||
ok = IndexToId(cx, newlen++, &id);
|
||||
if (!ok)
|
||||
goto out;
|
||||
ok = OBJ_SET_PROPERTY(cx, newarr, id, &v);
|
||||
ok = OBJ_SET_PROPERTY(cx, newarr, id, vp);
|
||||
if (!ok)
|
||||
goto out;
|
||||
break;
|
||||
@ -1721,25 +1741,25 @@ static JSFunctionSpec array_methods[] = {
|
||||
#if JS_HAS_MORE_PERL_FUN
|
||||
{"push", array_push, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"pop", array_pop, 0,JSFUN_GENERIC_NATIVE,0},
|
||||
{"shift", array_shift, 0,JSFUN_GENERIC_NATIVE,0},
|
||||
{"unshift", array_unshift, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"splice", array_splice, 2,JSFUN_GENERIC_NATIVE,0},
|
||||
{"shift", array_shift, 0,JSFUN_GENERIC_NATIVE,1},
|
||||
{"unshift", array_unshift, 1,JSFUN_GENERIC_NATIVE,1},
|
||||
{"splice", array_splice, 2,JSFUN_GENERIC_NATIVE,1},
|
||||
#endif
|
||||
|
||||
/* Python-esque sequence methods. */
|
||||
#if JS_HAS_SEQUENCE_OPS
|
||||
{"concat", array_concat, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"slice", array_slice, 2,JSFUN_GENERIC_NATIVE,0},
|
||||
{"concat", array_concat, 1,JSFUN_GENERIC_NATIVE,1},
|
||||
{"slice", array_slice, 2,JSFUN_GENERIC_NATIVE,1},
|
||||
#endif
|
||||
|
||||
#if JS_HAS_ARRAY_EXTRAS
|
||||
{"indexOf", array_indexOf, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"lastIndexOf", array_lastIndexOf, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"forEach", array_forEach, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"map", array_map, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"filter", array_filter, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"some", array_some, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"every", array_every, 1,JSFUN_GENERIC_NATIVE,0},
|
||||
{"forEach", array_forEach, 1,JSFUN_GENERIC_NATIVE,1},
|
||||
{"map", array_map, 1,JSFUN_GENERIC_NATIVE,1},
|
||||
{"filter", array_filter, 1,JSFUN_GENERIC_NATIVE,1},
|
||||
{"some", array_some, 1,JSFUN_GENERIC_NATIVE,1},
|
||||
{"every", array_every, 1,JSFUN_GENERIC_NATIVE,1},
|
||||
#endif
|
||||
|
||||
{0,0,0,0,0}
|
||||
|
Loading…
Reference in New Issue
Block a user