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 663389 4acbcf36de474be12c30a07a913236d8041d5319
parent 663388 4cc7890ba6e3dcad8304e8f9019111cac06de002
child 663390 453483778b6e1f09d3fddd9b89beb42abfaac200
push id79424
push userbmo:tchiovoloni@mozilla.com
push dateTue, 12 Sep 2017 23:17:54 +0000
reviewersjandem
bugs1393089
milestone57.0a1
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);