From 6bb24b8becd3c1bc5f1f6087ef03dd4671f0a2ee Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Thu, 20 Mar 2014 10:43:40 -0700 Subject: [PATCH] Bug 985733 - Refactor element-setting code to not conflate typed array and dense element setting. r=sfink --HG-- extra : rebase_source : 4aa073095fd71a8116460427b0e6b5108757dff2 --- js/src/jsobj.cpp | 23 ++++++++++- js/src/jsobj.h | 4 -- js/src/jsobjinlines.h | 19 --------- js/src/vm/TypedArrayObject.cpp | 75 ++++++++++++++-------------------- js/src/vm/TypedArrayObject.h | 4 +- 5 files changed, 53 insertions(+), 72 deletions(-) diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index d5c659a1a68..012c39bc856 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -5022,6 +5022,23 @@ baseops::SetPropertyHelper(typename ExecutionModeTraits::ContextType cxArg if (IsImplicitDenseOrTypedArrayElement(shape)) { uint32_t index = JSID_TO_INT(id); + + if (obj->is()) { + 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(), index, d); + return true; + } + bool definesPast; if (!WouldDefinePastNonwritableLength(cxArg, obj, index, strict, &definesPast)) return false; @@ -5033,8 +5050,10 @@ baseops::SetPropertyHelper(typename ExecutionModeTraits::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() && id == NameToId(cxArg->names().length)) { diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 4f2d69b7260..71827b0bba9 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -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()); diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index c77cbba0a34..b295f807315 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -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()) - return as().setElement(cx, index, val); - return setDenseElementIfHasType(index, val); -} - -inline bool -JSObject::setDenseOrTypedArrayElementWithType(js::ExclusiveContext *cx, uint32_t index, - const js::Value &val) -{ - if (is()) - return as().setElement(cx, index, val); - setDenseElementWithType(cx, index, val); - return true; -} - /* static */ inline bool JSObject::setSingletonType(js::ExclusiveContext *cx, js::HandleObject obj) { diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 61ca6919263..59ae8a75f24 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -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().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(obj->as().viewData()) + index) = val; + MOZ_ASSERT(index < tarray.length()); + static_cast(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::setIndexValue(cx, this, index, value); + TypedArrayObjectTemplate::setIndexValue(obj, index, d); break; case ScalarTypeDescr::TYPE_UINT8: - return TypedArrayObjectTemplate::setIndexValue(cx, this, index, value); + TypedArrayObjectTemplate::setIndexValue(obj, index, d); break; case ScalarTypeDescr::TYPE_UINT8_CLAMPED: - return TypedArrayObjectTemplate::setIndexValue(cx, this, index, value); + TypedArrayObjectTemplate::setIndexValue(obj, index, d); break; case ScalarTypeDescr::TYPE_INT16: - return TypedArrayObjectTemplate::setIndexValue(cx, this, index, value); + TypedArrayObjectTemplate::setIndexValue(obj, index, d); break; case ScalarTypeDescr::TYPE_UINT16: - return TypedArrayObjectTemplate::setIndexValue(cx, this, index, value); + TypedArrayObjectTemplate::setIndexValue(obj, index, d); break; case ScalarTypeDescr::TYPE_INT32: - return TypedArrayObjectTemplate::setIndexValue(cx, this, index, value); + TypedArrayObjectTemplate::setIndexValue(obj, index, d); break; case ScalarTypeDescr::TYPE_UINT32: - return TypedArrayObjectTemplate::setIndexValue(cx, this, index, value); + TypedArrayObjectTemplate::setIndexValue(obj, index, d); break; case ScalarTypeDescr::TYPE_FLOAT32: - return TypedArrayObjectTemplate::setIndexValue(cx, this, index, value); + TypedArrayObjectTemplate::setIndexValue(obj, index, d); break; case ScalarTypeDescr::TYPE_FLOAT64: - return TypedArrayObjectTemplate::setIndexValue(cx, this, index, value); + TypedArrayObjectTemplate::setIndexValue(obj, index, d); break; default: MOZ_ASSUME_UNREACHABLE("Unknown TypedArray type"); diff --git a/js/src/vm/TypedArrayObject.h b/js/src/vm/TypedArrayObject.h index 588084020d0..63a729d8c4e 100644 --- a/js/src/vm/TypedArrayObject.h +++ b/js/src/vm/TypedArrayObject.h @@ -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