Merge TM -> JM.
This commit is contained in:
@@ -353,8 +353,7 @@ IndexToId(JSContext* cx, JSObject* obj, jsdouble index, JSBool* hole, jsid* idp,
|
||||
* properly rooted and can be used as GC-protected storage for temporaries.
|
||||
*/
|
||||
static JSBool
|
||||
GetArrayElement(JSContext *cx, JSObject *obj, jsdouble index, JSBool *hole,
|
||||
Value *vp)
|
||||
GetElement(JSContext *cx, JSObject *obj, jsdouble index, JSBool *hole, Value *vp)
|
||||
{
|
||||
JS_ASSERT(index >= 0);
|
||||
if (obj->isDenseArray() && index < obj->getDenseArrayInitializedLength() &&
|
||||
@@ -399,6 +398,47 @@ GetArrayElement(JSContext *cx, JSObject *obj, jsdouble index, JSBool *hole,
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
GetElements(JSContext *cx, JSObject *aobj, jsuint length, Value *vp)
|
||||
{
|
||||
if (aobj->isDenseArray() && length <= aobj->getDenseArrayCapacity() &&
|
||||
!js_PrototypeHasIndexedProperties(cx, aobj)) {
|
||||
/* The prototype does not have indexed properties so hole = undefined */
|
||||
Value *srcbeg = aobj->getDenseArrayElements();
|
||||
Value *srcend = srcbeg + length;
|
||||
for (Value *dst = vp, *src = srcbeg; src < srcend; ++dst, ++src)
|
||||
*dst = src->isMagic(JS_ARRAY_HOLE) ? UndefinedValue() : *src;
|
||||
} else if (aobj->isArguments() && !aobj->isArgsLengthOverridden() &&
|
||||
!js_PrototypeHasIndexedProperties(cx, aobj)) {
|
||||
/*
|
||||
* Two cases, two loops: note how in the case of an active stack frame
|
||||
* backing aobj, even though we copy from fp->argv, we still must check
|
||||
* aobj->getArgsElement(i) for a hole, to handle a delete on the
|
||||
* corresponding arguments element. See args_delProperty.
|
||||
*/
|
||||
if (JSStackFrame *fp = (JSStackFrame *) aobj->getPrivate()) {
|
||||
JS_ASSERT(fp->numActualArgs() <= JS_ARGS_LENGTH_MAX);
|
||||
fp->forEachCanonicalActualArg(CopyNonHoleArgsTo(aobj, vp));
|
||||
} else {
|
||||
Value *srcbeg = aobj->getArgsElements();
|
||||
Value *srcend = srcbeg + length;
|
||||
for (Value *dst = vp, *src = srcbeg; src < srcend; ++dst, ++src)
|
||||
*dst = src->isMagic(JS_ARGS_HOLE) ? UndefinedValue() : *src;
|
||||
}
|
||||
} else {
|
||||
for (uintN i = 0; i < length; i++) {
|
||||
if (!aobj->getProperty(cx, INT_TO_JSID(jsint(i)), &vp[i]))
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare a dense array for a write to the specified index, updating its
|
||||
* length, capacity and initialized length as required.
|
||||
@@ -462,7 +502,7 @@ SetArrayElement(JSContext *cx, JSObject *obj, jsdouble index, const Value &v)
|
||||
|
||||
#ifdef JS_TRACER
|
||||
JSBool JS_FASTCALL
|
||||
js_Array_dense_setelem_uninitialized(JSContext *cx, JSObject *obj, jsint i)
|
||||
js_EnsureDenseArrayCapacity(JSContext *cx, JSObject *obj, jsint i)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Class *origObjClasp = obj->clasp;
|
||||
@@ -488,7 +528,7 @@ js_Array_dense_setelem_uninitialized(JSContext *cx, JSObject *obj, jsint i)
|
||||
return true;
|
||||
}
|
||||
/* This function and its callees do not touch any object's .clasp field. */
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, js_Array_dense_setelem_uninitialized, CONTEXT, OBJECT, INT32,
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, js_EnsureDenseArrayCapacity, CONTEXT, OBJECT, INT32,
|
||||
0, nanojit::ACCSET_STORE_ANY & ~tjit::ACCSET_OBJ_CLASP)
|
||||
#endif
|
||||
|
||||
@@ -728,7 +768,7 @@ js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
}
|
||||
|
||||
static JSBool
|
||||
array_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
array_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
@@ -851,24 +891,6 @@ js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
#ifdef JS_TRACER
|
||||
|
||||
JSBool FASTCALL
|
||||
js_Array_dense_setelem_hole(JSContext* cx, JSObject* obj, jsint i)
|
||||
{
|
||||
if (js_PrototypeHasIndexedProperties(cx, obj))
|
||||
return false;
|
||||
|
||||
jsuint u = jsuint(i);
|
||||
if (u >= obj->getArrayLength())
|
||||
obj->setArrayLength(cx, u + 1);
|
||||
return true;
|
||||
}
|
||||
/* storeAccSet == ACCSET_OBJ_PRIVATE: because it can set 'length'. */
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, js_Array_dense_setelem_hole, CONTEXT, OBJECT, INT32,
|
||||
0, tjit::ACCSET_OBJ_PRIVATE)
|
||||
#endif
|
||||
|
||||
static JSBool
|
||||
array_defineProperty(JSContext *cx, JSObject *obj, jsid id, const Value *value,
|
||||
PropertyOp getter, PropertyOp setter, uintN attrs)
|
||||
@@ -1192,7 +1214,7 @@ array_toSource(JSContext *cx, uintN argc, Value *vp)
|
||||
/* Use vp to locally root each element value. */
|
||||
JSBool hole;
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, index, &hole, vp)) {
|
||||
!GetElement(cx, obj, index, &hole, vp)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1296,7 +1318,7 @@ array_toString_sub(JSContext *cx, JSObject *obj, JSBool locale,
|
||||
/* Use rval to locally root each element value. */
|
||||
JSBool hole;
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, index, &hole, rval)) {
|
||||
!GetElement(cx, obj, index, &hole, rval)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1540,8 +1562,8 @@ array_reverse(JSContext *cx, uintN argc, Value *vp)
|
||||
for (jsuint i = 0, half = len / 2; i < half; i++) {
|
||||
JSBool hole, hole2;
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, i, &hole, tvr.addr()) ||
|
||||
!GetArrayElement(cx, obj, len - i - 1, &hole2, vp) ||
|
||||
!GetElement(cx, obj, i, &hole, tvr.addr()) ||
|
||||
!GetElement(cx, obj, len - i - 1, &hole2, vp) ||
|
||||
!SetOrDeleteArrayElement(cx, obj, len - i - 1, hole, tvr.value()) ||
|
||||
!SetOrDeleteArrayElement(cx, obj, i, hole2, *vp)) {
|
||||
return false;
|
||||
@@ -1861,7 +1883,7 @@ js::array_sort(JSContext *cx, uintN argc, Value *vp)
|
||||
JSBool hole;
|
||||
vec[newlen].setNull();
|
||||
tvr.changeLength(newlen + 1);
|
||||
if (!GetArrayElement(cx, obj, i, &hole, &vec[newlen]))
|
||||
if (!GetElement(cx, obj, i, &hole, &vec[newlen]))
|
||||
return false;
|
||||
|
||||
if (hole)
|
||||
@@ -2087,10 +2109,15 @@ js_ArrayCompPush(JSContext *cx, JSObject *obj, const Value &vp)
|
||||
JSBool JS_FASTCALL
|
||||
js_ArrayCompPush_tn(JSContext *cx, JSObject *obj, ValueArgType v)
|
||||
{
|
||||
return ArrayCompPushImpl(cx, obj, ValueArgToConstRef(v));
|
||||
if (!ArrayCompPushImpl(cx, obj, ValueArgToConstRef(v))) {
|
||||
SetBuiltinError(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return cx->tracerState->builtinStatus == 0;
|
||||
}
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, js_ArrayCompPush_tn, CONTEXT, OBJECT, VALUE,
|
||||
0, nanojit::ACCSET_STORE_ANY)
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL_FAIL, js_ArrayCompPush_tn, CONTEXT, OBJECT,
|
||||
VALUE, 0, nanojit::ACCSET_STORE_ANY)
|
||||
|
||||
static JSBool
|
||||
array_push(JSContext *cx, uintN argc, Value *vp)
|
||||
@@ -2123,7 +2150,7 @@ array_pop_slowly(JSContext *cx, JSObject* obj, Value *vp)
|
||||
index--;
|
||||
|
||||
/* Get the to-be-deleted property's value into vp. */
|
||||
if (!GetArrayElement(cx, obj, index, &hole, vp))
|
||||
if (!GetElement(cx, obj, index, &hole, vp))
|
||||
return JS_FALSE;
|
||||
if (!hole && !DeleteArrayElement(cx, obj, index, true))
|
||||
return JS_FALSE;
|
||||
@@ -2143,7 +2170,7 @@ array_pop_dense(JSContext *cx, JSObject* obj, Value *vp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
index--;
|
||||
if (!GetArrayElement(cx, obj, index, &hole, vp))
|
||||
if (!GetElement(cx, obj, index, &hole, vp))
|
||||
return JS_FALSE;
|
||||
if (!hole && !DeleteArrayElement(cx, obj, index, true))
|
||||
return JS_FALSE;
|
||||
@@ -2196,14 +2223,14 @@ array_shift(JSContext *cx, uintN argc, Value *vp)
|
||||
}
|
||||
|
||||
/* Get the to-be-deleted property's value into vp ASAP. */
|
||||
if (!GetArrayElement(cx, obj, 0, &hole, vp))
|
||||
if (!GetElement(cx, obj, 0, &hole, vp))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Slide down the array above the first element. */
|
||||
AutoValueRooter tvr(cx);
|
||||
for (i = 0; i != length; i++) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, i + 1, &hole, tvr.addr()) ||
|
||||
!GetElement(cx, obj, i + 1, &hole, tvr.addr()) ||
|
||||
!SetOrDeleteArrayElement(cx, obj, i, hole, tvr.value())) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@@ -2251,7 +2278,7 @@ array_unshift(JSContext *cx, uintN argc, Value *vp)
|
||||
do {
|
||||
--last, --upperIndex;
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, last, &hole, tvr.addr()) ||
|
||||
!GetElement(cx, obj, last, &hole, tvr.addr()) ||
|
||||
!SetOrDeleteArrayElement(cx, obj, upperIndex, hole, tvr.value())) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@@ -2365,7 +2392,7 @@ array_splice(JSContext *cx, uintN argc, Value *vp)
|
||||
} else {
|
||||
for (last = begin; last < end; last++) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, last, &hole, tvr.addr())) {
|
||||
!GetElement(cx, obj, last, &hole, tvr.addr())) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
@@ -2399,7 +2426,7 @@ array_splice(JSContext *cx, uintN argc, Value *vp)
|
||||
/* (uint) end could be 0, so we can't use a vanilla >= test. */
|
||||
while (last-- > end) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, last, &hole, tvr.addr()) ||
|
||||
!GetElement(cx, obj, last, &hole, tvr.addr()) ||
|
||||
!SetOrDeleteArrayElement(cx, obj, last + delta, hole, tvr.value())) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@@ -2420,7 +2447,7 @@ array_splice(JSContext *cx, uintN argc, Value *vp)
|
||||
} else {
|
||||
for (last = end; last < length; last++) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, last, &hole, tvr.addr()) ||
|
||||
!GetElement(cx, obj, last, &hole, tvr.addr()) ||
|
||||
!SetOrDeleteArrayElement(cx, obj, last - delta, hole, tvr.value())) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@@ -2505,7 +2532,7 @@ array_concat(JSContext *cx, uintN argc, Value *vp)
|
||||
for (jsuint slot = 0; slot < alength; slot++) {
|
||||
JSBool hole;
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, aobj, slot, &hole, tvr.addr())) {
|
||||
!GetElement(cx, aobj, slot, &hole, tvr.addr())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2615,7 +2642,7 @@ array_slice(JSContext *cx, uintN argc, Value *vp)
|
||||
AutoValueRooter tvr(cx);
|
||||
for (slot = begin; slot < end; slot++) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, slot, &hole, tvr.addr())) {
|
||||
!GetElement(cx, obj, slot, &hole, tvr.addr())) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (!hole && !SetArrayElement(cx, nobj, slot - begin, tvr.value()))
|
||||
@@ -2679,7 +2706,7 @@ array_indexOfHelper(JSContext *cx, JSBool isLast, uintN argc, Value *vp)
|
||||
|
||||
for (;;) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetArrayElement(cx, obj, (jsuint)i, &hole, vp)) {
|
||||
!GetElement(cx, obj, (jsuint)i, &hole, vp)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (!hole && StrictlyEqual(cx, *vp, tosearch)) {
|
||||
@@ -2772,7 +2799,7 @@ array_extra(JSContext *cx, ArrayExtraMode mode, uintN argc, Value *vp)
|
||||
} else {
|
||||
JSBool hole;
|
||||
do {
|
||||
if (!GetArrayElement(cx, obj, start, &hole, vp))
|
||||
if (!GetElement(cx, obj, start, &hole, vp))
|
||||
return JS_FALSE;
|
||||
start += step;
|
||||
} while (hole && start != end);
|
||||
@@ -2835,7 +2862,7 @@ array_extra(JSContext *cx, ArrayExtraMode mode, uintN argc, Value *vp)
|
||||
for (jsint i = start; i != end; i += step) {
|
||||
JSBool hole;
|
||||
ok = JS_CHECK_OPERATION_LIMIT(cx) &&
|
||||
GetArrayElement(cx, obj, i, &hole, tvr.addr());
|
||||
GetElement(cx, obj, i, &hole, tvr.addr());
|
||||
if (!ok)
|
||||
goto out;
|
||||
if (hole)
|
||||
|
||||
Reference in New Issue
Block a user