Bug 985733 - Refactor element-setting code to not conflate typed array and dense element setting. r=sfink

--HG--
extra : rebase_source : 4aa073095fd71a8116460427b0e6b5108757dff2
This commit is contained in:
Jeff Walden 2014-03-20 10:43:40 -07:00
parent 3ee90d23a2
commit 6bb24b8bec
5 changed files with 53 additions and 72 deletions

View File

@ -5022,6 +5022,23 @@ baseops::SetPropertyHelper(typename ExecutionModeTraits<mode>::ContextType cxArg
if (IsImplicitDenseOrTypedArrayElement(shape)) {
uint32_t index = JSID_TO_INT(id);
if (obj->is<TypedArrayObject>()) {
double d;
if (mode == ParallelExecution) {
// Bail if converting the value might invoke user-defined
// conversions.
if (vp.isObject())
return false;
}
if (!ToDoubleForTypedArray(cxArg, vp, &d))
return false;
TypedArrayObject::setElement(obj->as<TypedArrayObject>(), index, d);
return true;
}
bool definesPast;
if (!WouldDefinePastNonwritableLength(cxArg, obj, index, strict, &definesPast))
return false;
@ -5033,8 +5050,10 @@ baseops::SetPropertyHelper(typename ExecutionModeTraits<mode>::ContextType cxArg
}
if (mode == ParallelExecution)
return obj->setDenseOrTypedArrayElementIfHasType(cxArg, index, vp);
return obj->setDenseOrTypedArrayElementWithType(cxArg->asJSContext(), index, vp);
return obj->setDenseElementIfHasType(index, vp);
obj->setDenseElementWithType(cxArg->asJSContext(), index, vp);
return true;
}
if (obj->is<ArrayObject>() && id == NameToId(cxArg->names().length)) {

View File

@ -651,10 +651,6 @@ class JSObject : public js::ObjectImpl
js::HandleObject obj, uint32_t index);
inline js::Value getDenseOrTypedArrayElement(uint32_t idx);
inline bool setDenseOrTypedArrayElementIfHasType(js::ThreadSafeContext *cx, uint32_t index,
const js::Value &val);
inline bool setDenseOrTypedArrayElementWithType(js::ExclusiveContext *cx, uint32_t index,
const js::Value &val);
void copyDenseElements(uint32_t dstStart, const js::Value *src, uint32_t count) {
JS_ASSERT(dstStart + count <= getDenseCapacity());

View File

@ -351,25 +351,6 @@ JSObject::getDenseOrTypedArrayElement(uint32_t idx)
return getDenseElement(idx);
}
inline bool
JSObject::setDenseOrTypedArrayElementIfHasType(js::ThreadSafeContext *cx, uint32_t index,
const js::Value &val)
{
if (is<js::TypedArrayObject>())
return as<js::TypedArrayObject>().setElement(cx, index, val);
return setDenseElementIfHasType(index, val);
}
inline bool
JSObject::setDenseOrTypedArrayElementWithType(js::ExclusiveContext *cx, uint32_t index,
const js::Value &val)
{
if (is<js::TypedArrayObject>())
return as<js::TypedArrayObject>().setElement(cx, index, val);
setDenseElementWithType(cx, index, val);
return true;
}
/* static */ inline bool
JSObject::setSingletonType(js::ExclusiveContext *cx, js::HandleObject obj)
{

View File

@ -166,25 +166,25 @@ js::ClampDoubleToUint8(const double x)
return y;
}
static bool
ToDoubleForTypedArray(ThreadSafeContext *cx, const Value &vp, double *d)
bool
js::ToDoubleForTypedArray(ThreadSafeContext *cx, HandleValue vp, double *d)
{
if (vp.isDouble()) {
*d = vp.toDouble();
} else if (vp.isInt32()) {
*d = vp.toInt32();
} else if (vp.isNull()) {
*d = 0.0;
} else if (vp.isPrimitive()) {
JS_ASSERT(vp.isString() || vp.isUndefined() || vp.isBoolean());
if (vp.isString()) {
if (!StringToNumber(cx, vp.toString(), d))
return false;
} else if (vp.isUndefined()) {
*d = GenericNaN();
} else {
*d = double(vp.toBoolean());
}
} else if (vp.isString()) {
if (!StringToNumber(cx, vp.toString(), d))
return false;
} else if (vp.isUndefined()) {
*d = GenericNaN();
} else if (vp.isBoolean()) {
*d = double(vp.toBoolean());
} else {
// non-primitive assignments become NaN or 0 (for float/int arrays)
// Non-primitive assignments become NaN or 0 (for float/int arrays).
MOZ_ASSERT(vp.isObject());
*d = GenericNaN();
}
@ -242,21 +242,9 @@ class TypedArrayObjectTemplate : public TypedArrayObject
return v.isObject() && v.toObject().hasClass(fastClass());
}
static bool
setIndexValue(ThreadSafeContext *cx, JSObject *tarray, uint32_t index, const Value &value)
static void
setIndexValue(TypedArrayObject &tarray, uint32_t index, double d)
{
JS_ASSERT(tarray);
JS_ASSERT(index < tarray->as<TypedArrayObject>().length());
if (value.isInt32()) {
setIndex(tarray, index, NativeType(value.toInt32()));
return true;
}
double d;
if (!ToDoubleForTypedArray(cx, value, &d))
return false;
// If the array is an integer array, we only handle up to
// 32-bit ints from this point on. if we want to handle
// 64-bit ints, we'll need some changes.
@ -277,8 +265,6 @@ class TypedArrayObjectTemplate : public TypedArrayObject
int32_t n = ToInt32(d);
setIndex(tarray, index, NativeType(n));
}
return true;
}
static TypedArrayObject *
@ -825,9 +811,10 @@ class TypedArrayObjectTemplate : public TypedArrayObject
}
static void
setIndex(JSObject *obj, uint32_t index, NativeType val)
setIndex(TypedArrayObject &tarray, uint32_t index, NativeType val)
{
*(static_cast<NativeType*>(obj->as<TypedArrayObject>().viewData()) + index) = val;
MOZ_ASSERT(index < tarray.length());
static_cast<NativeType*>(tarray.viewData())[index] = val;
}
static Value getIndexValue(JSObject *tarray, uint32_t index);
@ -1973,38 +1960,36 @@ TypedArrayObject::getElement(uint32_t index)
}
}
bool
TypedArrayObject::setElement(ThreadSafeContext *cx, uint32_t index, const Value &value)
void
TypedArrayObject::setElement(TypedArrayObject &obj, uint32_t index, double d)
{
JS_ASSERT(index < length());
switch (type()) {
switch (obj.type()) {
case ScalarTypeDescr::TYPE_INT8:
return TypedArrayObjectTemplate<int8_t>::setIndexValue(cx, this, index, value);
TypedArrayObjectTemplate<int8_t>::setIndexValue(obj, index, d);
break;
case ScalarTypeDescr::TYPE_UINT8:
return TypedArrayObjectTemplate<uint8_t>::setIndexValue(cx, this, index, value);
TypedArrayObjectTemplate<uint8_t>::setIndexValue(obj, index, d);
break;
case ScalarTypeDescr::TYPE_UINT8_CLAMPED:
return TypedArrayObjectTemplate<uint8_clamped>::setIndexValue(cx, this, index, value);
TypedArrayObjectTemplate<uint8_clamped>::setIndexValue(obj, index, d);
break;
case ScalarTypeDescr::TYPE_INT16:
return TypedArrayObjectTemplate<int16_t>::setIndexValue(cx, this, index, value);
TypedArrayObjectTemplate<int16_t>::setIndexValue(obj, index, d);
break;
case ScalarTypeDescr::TYPE_UINT16:
return TypedArrayObjectTemplate<uint16_t>::setIndexValue(cx, this, index, value);
TypedArrayObjectTemplate<uint16_t>::setIndexValue(obj, index, d);
break;
case ScalarTypeDescr::TYPE_INT32:
return TypedArrayObjectTemplate<int32_t>::setIndexValue(cx, this, index, value);
TypedArrayObjectTemplate<int32_t>::setIndexValue(obj, index, d);
break;
case ScalarTypeDescr::TYPE_UINT32:
return TypedArrayObjectTemplate<uint32_t>::setIndexValue(cx, this, index, value);
TypedArrayObjectTemplate<uint32_t>::setIndexValue(obj, index, d);
break;
case ScalarTypeDescr::TYPE_FLOAT32:
return TypedArrayObjectTemplate<float>::setIndexValue(cx, this, index, value);
TypedArrayObjectTemplate<float>::setIndexValue(obj, index, d);
break;
case ScalarTypeDescr::TYPE_FLOAT64:
return TypedArrayObjectTemplate<double>::setIndexValue(cx, this, index, value);
TypedArrayObjectTemplate<double>::setIndexValue(obj, index, d);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unknown TypedArray type");

View File

@ -79,7 +79,7 @@ class TypedArrayObject : public ArrayBufferViewObject
inline bool isArrayIndex(jsid id, uint32_t *ip = nullptr);
Value getElement(uint32_t index);
bool setElement(ThreadSafeContext *cx, uint32_t index, const Value &value);
static void setElement(TypedArrayObject &obj, uint32_t index, double d);
void neuter(void *newData);
@ -337,7 +337,7 @@ ClampIntForUint8Array(int32_t x)
return x;
}
bool ToDoubleForTypedArray(JSContext *cx, JS::HandleValue vp, double *d);
bool ToDoubleForTypedArray(ThreadSafeContext *cx, JS::HandleValue vp, double *d);
} // namespace js