Bug 1393089 - Part 6: Reduce code duplications by sync'ing TypedArray constructor to latest spec. r=jandem
authorAndré Bargull <andre.bargull@gmail.com>
Sat, 09 Sep 2017 13:07:39 +0200
changeset 380332 4acbcf36de474be12c30a07a913236d8041d5319
parent 380331 4cc7890ba6e3dcad8304e8f9019111cac06de002
child 380333 453483778b6e1f09d3fddd9b89beb42abfaac200
push id94893
push userryanvm@gmail.com
push dateTue, 12 Sep 2017 19:25:04 +0000
treeherdermozilla-inbound@453483778b6e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1393089
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1393089 - Part 6: Reduce code duplications by sync'ing TypedArray constructor to latest spec. r=jandem
js/src/vm/TypedArrayObject.cpp
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -974,22 +974,16 @@ class TypedArrayObjectTemplate : public 
         return makeInstance(cx, buffer, 0, uint32_t(nelements), proto);
     }
 
     static bool
     AllocateArrayBuffer(JSContext* cx, HandleObject ctor,
                         uint32_t count, uint32_t unit,
                         MutableHandle<ArrayBufferObject*> buffer);
 
-    static bool
-    CloneArrayBufferNoCopy(JSContext* cx, Handle<ArrayBufferObjectMaybeShared*> srcBuffer,
-                           bool isWrapped, uint32_t srcByteOffset, uint32_t srcLength,
-                           SpeciesConstructorOverride override,
-                           MutableHandle<ArrayBufferObject*> buffer);
-
     static JSObject*
     fromArray(JSContext* cx, HandleObject other, HandleObject proto = nullptr);
 
     static JSObject*
     fromTypedArray(JSContext* cx, HandleObject other, bool isWrapped, HandleObject proto);
 
     static JSObject*
     fromObject(JSContext* cx, HandleObject other, HandleObject proto);
@@ -1094,89 +1088,48 @@ GetSpeciesConstructor(JSContext* cx, Han
 
     RootedObject wrappedObj(cx, obj);
     if (isWrapped && !cx->compartment()->wrap(cx, &wrappedObj))
         return nullptr;
 
     return SpeciesConstructor(cx, wrappedObj, defaultCtor, IsArrayBufferSpecies);
 }
 
-// ES 2017 draft rev 8633ffd9394b203b8876bb23cb79aff13eb07310 24.1.1.4.
-template<typename T>
-/* static */ bool
-TypedArrayObjectTemplate<T>::CloneArrayBufferNoCopy(JSContext* cx,
-                                                    Handle<ArrayBufferObjectMaybeShared*> srcBuffer,
-                                                    bool isWrapped, uint32_t srcByteOffset,
-                                                    uint32_t srcLength,
-                                                    SpeciesConstructorOverride override,
-                                                    MutableHandle<ArrayBufferObject*> buffer)
-{
-    // Step 1 (skipped).
-
-    // Step 2.a.
-    RootedObject cloneCtor(cx, GetSpeciesConstructor(cx, srcBuffer, isWrapped, override));
-    if (!cloneCtor)
-        return false;
-
-    // Step 2.b.
-    if (srcBuffer->isDetached()) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
-        return false;
-    }
-
-    // Steps 3-4 (skipped).
-
-    // Steps 5.
-    if (!AllocateArrayBuffer(cx, cloneCtor, srcLength, 1, buffer))
-        return false;
-
-    // Step 6.
-    if (srcBuffer->isDetached()) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
-        return false;
-    }
-
-    // Steps 7-8 (done in caller).
-
-    // Step 9.
-    return true;
-}
-
 template<typename T>
 /* static */ JSObject*
 TypedArrayObjectTemplate<T>::fromArray(JSContext* cx, HandleObject other,
                                        HandleObject proto /* = nullptr */)
 {
     // Allow nullptr proto for FriendAPI methods, which don't care about
     // subclassing.
     if (other->is<TypedArrayObject>())
         return fromTypedArray(cx, other, /* wrapped= */ false, proto);
 
     if (other->is<WrapperObject>() && UncheckedUnwrap(other)->is<TypedArrayObject>())
         return fromTypedArray(cx, other, /* wrapped= */ true, proto);
 
     return fromObject(cx, other, proto);
 }
 
-// ES2017 draft rev 6390c2f1b34b309895d31d8c0512eac8660a0210
+// ES2018 draft rev 272beb67bc5cd9fd18a220665198384108208ee1
 // 22.2.4.3 TypedArray ( typedArray )
 template<typename T>
 /* static */ JSObject*
 TypedArrayObjectTemplate<T>::fromTypedArray(JSContext* cx, HandleObject other, bool isWrapped,
                                             HandleObject proto)
 {
     // Step 1.
     MOZ_ASSERT_IF(!isWrapped, other->is<TypedArrayObject>());
     MOZ_ASSERT_IF(isWrapped,
                   other->is<WrapperObject>() &&
                   UncheckedUnwrap(other)->is<TypedArrayObject>());
 
     // Step 2 (Already performed in caller).
 
-    // Step 4 (Allocation deferred until later).
+    // Steps 3-4 (Allocation deferred until later).
 
     // Step 5.
     Rooted<TypedArrayObject*> srcArray(cx);
     if (!isWrapped) {
         srcArray = &other->as<TypedArrayObject>();
         if (!TypedArrayObject::ensureHasBuffer(cx, srcArray))
             return nullptr;
     } else {
@@ -1203,71 +1156,71 @@ TypedArrayObjectTemplate<T>::fromTypedAr
     }
 
     // Step 9.
     uint32_t elementLength = srcArray->length();
 
     // Steps 10-11.
     Scalar::Type srcType = srcArray->type();
 
-    // Step 12 (skipped).
-
-    // Step 13.
-    uint32_t srcByteOffset = srcArray->byteOffset();
+    // Steps 12-13 (skipped).
 
     // Steps 16-17.
     bool isShared = srcArray->isSharedMemory();
     SpeciesConstructorOverride override = isShared ? SpeciesConstructorOverride::ArrayBuffer
                                                    : SpeciesConstructorOverride::None;
 
-    // Steps 8, 16-17.
+    RootedObject bufferCtor(cx, GetSpeciesConstructor(cx, srcData, isWrapped, override));
+    if (!bufferCtor)
+        return nullptr;
+
+    // Steps 8, 18-19.
     Rooted<ArrayBufferObject*> buffer(cx);
     if (ArrayTypeID() == srcType) {
-        // Step 16.a.
-        uint32_t srcLength = srcArray->byteLength();
-
-        // Steps 16.b-c.
-        if (!CloneArrayBufferNoCopy(cx, srcData, isWrapped, srcByteOffset, srcLength, override,
-                                    &buffer))
-        {
-            return nullptr;
-        }
-    } else {
-        // Steps 17.a-b.
-        RootedObject bufferCtor(cx, GetSpeciesConstructor(cx, srcData, isWrapped, override));
-        if (!bufferCtor)
-            return nullptr;
-
-        // Steps 14-15, 17.c.
-        if (!AllocateArrayBuffer(cx, bufferCtor, elementLength, BYTES_PER_ELEMENT, &buffer))
-            return nullptr;
-
-        // Step 17.d.
-        if (srcArray->hasDetachedBuffer()) {
+        // Step 18.a.
+        if (srcData->isDetached()) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
             return nullptr;
         }
+
+        // Step 15.
+        uint32_t byteLength = srcArray->byteLength();
+
+        // Step 18.b.
+        // 24.1.1.4 CloneArrayBuffer(...), steps 1-3.
+        if (!AllocateArrayBuffer(cx, bufferCtor, byteLength, 1, &buffer))
+            return nullptr;
+    } else {
+        // Steps 14-15, 19.a.
+        if (!AllocateArrayBuffer(cx, bufferCtor, elementLength, BYTES_PER_ELEMENT, &buffer))
+            return nullptr;
     }
 
-    // Steps 3-4 (remaining part), 18-21.
+    // Step 19.b or 24.1.1.4 step 4.
+    if (srcData->isDetached()) {
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
+        return nullptr;
+    }
+
+    // Steps 3-4 (remaining part), 20-23.
     Rooted<TypedArrayObject*> obj(cx, makeInstance(cx, buffer, 0, elementLength, proto));
     if (!obj)
         return nullptr;
 
-    // Steps 17.e-h or 24.1.1.4 step 8.
+    // Steps 19.c-f or 24.1.1.4 steps 5-7.
     MOZ_ASSERT(!obj->isSharedMemory());
     if (isShared) {
         if (!ElementSpecific<T, SharedOps>::setFromTypedArray(obj, srcArray, 0))
             return nullptr;
     } else {
         if (!ElementSpecific<T, UnsharedOps>::setFromTypedArray(obj, srcArray, 0))
             return nullptr;
     }
 
-    // Step 22.
+    // Step 24.
     return obj;
 }
 
 static MOZ_ALWAYS_INLINE bool
 IsOptimizableInit(JSContext* cx, HandleObject iterable, bool* optimized)
 {
     MOZ_ASSERT(!*optimized);