diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index ed5d436c76d..a665c641b22 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -627,44 +627,8 @@ DefinePropertyOnTypedArray(JSContext* cx, HandleObject obj, HandleId id, MOZ_ASSERT(IsAnyTypedArray(obj)); // Steps 3.a-c. uint64_t index; - if (IsTypedArrayIndex(id, &index)) { - // These are all substeps of 3.c. - // Steps i-vi. - // We (wrongly) ignore out of range defines with a value. - if (index >= AnyTypedArrayLength(obj)) - return result.succeed(); - - // Step vii. - if (desc.isAccessorDescriptor()) - return result.fail(JSMSG_CANT_REDEFINE_PROP); - - // Step viii. - if (desc.hasConfigurable() && desc.configurable()) - return result.fail(JSMSG_CANT_REDEFINE_PROP); - - // Step ix. - if (desc.hasEnumerable() && !desc.enumerable()) - return result.fail(JSMSG_CANT_REDEFINE_PROP); - - // Step x. - if (desc.hasWritable() && !desc.writable()) - return result.fail(JSMSG_CANT_REDEFINE_PROP); - - // Step xi. - if (desc.hasValue()) { - double d; - if (!ToNumber(cx, desc.value(), &d)) - return false; - - if (obj->is()) - TypedArrayObject::setElement(obj->as(), index, d); - else - SharedTypedArrayObject::setElement(obj->as(), index, d); - } - - // Step xii. - return result.succeed(); - } + if (IsTypedArrayIndex(id, &index)) + return DefineTypedArrayElement(cx, obj, index, desc, result); // Step 4. return DefinePropertyOnObject(cx, obj.as(), id, desc, result); diff --git a/js/src/vm/NativeObject.cpp b/js/src/vm/NativeObject.cpp index 9398adb6e5c..f86a6b6bb87 100644 --- a/js/src/vm/NativeObject.cpp +++ b/js/src/vm/NativeObject.cpp @@ -1302,10 +1302,13 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId return result.fail(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH); } } else if (IsAnyTypedArray(obj)) { - // Don't define new indexed properties on typed arrays. + // 9.4.5.3 step 3. Indexed properties of typed arrays are special. uint64_t index; - if (IsTypedArrayIndex(id, &index)) - return result.succeed(); + if (IsTypedArrayIndex(id, &index)) { + if (!cx->shouldBeJSContext()) + return false; + return DefineTypedArrayElement(cx->asJSContext(), obj, index, desc_, result); + } } Rooted desc(cx, desc_); diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 7a32a41e601..827e9af3128 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -2105,6 +2105,51 @@ js::StringIsTypedArrayIndex(const char16_t* s, size_t length, uint64_t* indexp); template bool js::StringIsTypedArrayIndex(const Latin1Char* s, size_t length, uint64_t* indexp); +/* ES6 draft rev 34 (2015 Feb 20) 9.4.5.3 [[DefineOwnProperty]] step 3.c. */ +bool +js::DefineTypedArrayElement(JSContext *cx, HandleObject obj, uint64_t index, + Handle desc, ObjectOpResult &result) +{ + MOZ_ASSERT(IsAnyTypedArray(obj)); + + // These are all substeps of 3.c. + // Steps i-vi. + // We (wrongly) ignore out of range defines with a value. + if (index >= AnyTypedArrayLength(obj)) + return result.succeed(); + + // Step vii. + if (desc.isAccessorDescriptor()) + return result.fail(JSMSG_CANT_REDEFINE_PROP); + + // Step viii. + if (desc.hasConfigurable() && desc.configurable()) + return result.fail(JSMSG_CANT_REDEFINE_PROP); + + // Step ix. + if (desc.hasEnumerable() && !desc.enumerable()) + return result.fail(JSMSG_CANT_REDEFINE_PROP); + + // Step x. + if (desc.hasWritable() && !desc.writable()) + return result.fail(JSMSG_CANT_REDEFINE_PROP); + + // Step xi. + if (desc.hasValue()) { + double d; + if (!ToNumber(cx, desc.value(), &d)) + return false; + + if (obj->is()) + TypedArrayObject::setElement(obj->as(), index, d); + else + SharedTypedArrayObject::setElement(obj->as(), index, d); + } + + // Step xii. + return result.succeed(); +} + /* JS Friend API */ JS_FRIEND_API(bool) diff --git a/js/src/vm/TypedArrayObject.h b/js/src/vm/TypedArrayObject.h index 04f6ec129d2..6822e2ade09 100644 --- a/js/src/vm/TypedArrayObject.h +++ b/js/src/vm/TypedArrayObject.h @@ -277,6 +277,14 @@ IsTypedArrayIndex(jsid id, uint64_t* indexp) return StringIsTypedArrayIndex(s, length, indexp); } +/* + * Implements [[DefineOwnProperty]] for TypedArrays and SharedTypedArrays + * when the property key is a TypedArray index. + */ +bool +DefineTypedArrayElement(JSContext *cx, HandleObject arr, uint64_t index, + Handle desc, ObjectOpResult &result); + static inline unsigned TypedArrayShift(Scalar::Type viewType) {