Backed out changeset 51249df95c69 (bug 1165053)
authorTooru Fujisawa <arai_a@mac.com>
Mon, 28 Mar 2016 06:49:58 +0900
changeset 290678 8b4dc7fe55213d623cb903a9ae941b0c55b4ceca
parent 290677 b62e02bd33f9e6852fa629b8e8f3a1c6d9b3c05e
child 290679 e1bbed330deb558d6fa48736b80a3ab082d6f836
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1165053
milestone48.0a1
backs out51249df95c69025fc997ef74a38be9ee7a89dfcd
Backed out changeset 51249df95c69 (bug 1165053)
js/src/tests/ecma_6/TypedArray/Tconstructor-fromTypedArray-byteLength.js
js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species-wrap.js
js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species.js
js/src/vm/ArrayBufferObject-inl.h
js/src/vm/ArrayBufferObject.h
js/src/vm/TypedArrayObject.cpp
deleted file mode 100644
--- a/js/src/tests/ecma_6/TypedArray/Tconstructor-fromTypedArray-byteLength.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const constructors = [
-    Int8Array,
-    Uint8Array,
-    Uint8ClampedArray,
-    Int16Array,
-    Uint16Array,
-    Int32Array,
-    Uint32Array,
-    Float32Array,
-    Float64Array
-];
-
-const sharedConstructors = [];
-
-if (typeof SharedArrayBuffer != "undefined")
-    sharedConstructors.push(sharedConstructor(Int8Array),
-                            sharedConstructor(Uint8Array),
-                            sharedConstructor(Int16Array),
-                            sharedConstructor(Uint16Array),
-                            sharedConstructor(Int32Array),
-                            sharedConstructor(Uint32Array),
-                            sharedConstructor(Float32Array),
-                            sharedConstructor(Float64Array));
-
-var g = newGlobal();
-
-var arr = [1, 2, 3];
-for (var constructor of constructors.concat(sharedConstructors)) {
-    var tarr = new constructor(arr);
-    for (var constructor2 of constructors) {
-        var copied = new constructor2(tarr);
-        assertEq(copied.buffer.byteLength, arr.length * constructor2.BYTES_PER_ELEMENT);
-
-        g.tarr = tarr;
-        copied = g.eval(`new ${constructor2.name}(tarr);`);
-        assertEq(copied.buffer.byteLength, arr.length * constructor2.BYTES_PER_ELEMENT);
-    }
-}
-
-if (typeof reportCompare === "function")
-    reportCompare(true, true);
deleted file mode 100644
--- a/js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species-wrap.js
+++ /dev/null
@@ -1,75 +0,0 @@
-// |reftest| skip-if(!xulRuntime.shell)
-
-const constructors = [
-    Int8Array,
-    Uint8Array,
-    Uint8ClampedArray,
-    Int16Array,
-    Uint16Array,
-    Int32Array,
-    Uint32Array,
-    Float32Array,
-    Float64Array
-];
-
-let g = newGlobal();
-
-// Both TypedArray and ArrayBuffer from different global.
-for (let ctor of constructors) {
-  let a = g.eval(`new ${ctor.name}([1, 2, 3, 4, 5]);`);
-  for (let ctor2 of constructors) {
-    let b = new ctor2(a);
-    assertEq(Object.getPrototypeOf(b).constructor, ctor2);
-    assertEq(Object.getPrototypeOf(b.buffer).constructor, g.ArrayBuffer);
-  }
-}
-
-// Only ArrayBuffer from different global.
-let called = false;
-let origSpecies = Object.getOwnPropertyDescriptor(ArrayBuffer, Symbol.species);
-let modSpecies = {
-  get() {
-    called = true;
-    return g.ArrayBuffer;
-  }
-};
-for (let ctor of constructors) {
-  let a = new ctor([1, 2, 3, 4, 5]);
-  for (let ctor2 of constructors) {
-    called = false;
-    Object.defineProperty(ArrayBuffer, Symbol.species, modSpecies);
-    let b = new ctor2(a);
-    Object.defineProperty(ArrayBuffer, Symbol.species, origSpecies);
-    assertEq(called, true);
-    assertEq(Object.getPrototypeOf(b).constructor, ctor2);
-    assertEq(Object.getPrototypeOf(b.buffer).constructor, g.ArrayBuffer);
-  }
-}
-
-// Only TypedArray from different global.
-g.otherArrayBuffer = ArrayBuffer;
-g.eval(`
-var called = false;
-var origSpecies = Object.getOwnPropertyDescriptor(ArrayBuffer, Symbol.species);
-var modSpecies = {
-  get() {
-    called = true;
-    return otherArrayBuffer;
-  }
-};
-`);
-for (let ctor of constructors) {
-  let a = g.eval(`new ${ctor.name}([1, 2, 3, 4, 5]);`);
-  for (let ctor2 of constructors) {
-    g.called = false;
-    g.eval(`Object.defineProperty(ArrayBuffer, Symbol.species, modSpecies);`);
-    let b = new ctor2(a);
-    g.eval(`Object.defineProperty(ArrayBuffer, Symbol.species, origSpecies);`);
-    assertEq(g.called, true);
-    assertEq(Object.getPrototypeOf(b).constructor, ctor2);
-    assertEq(Object.getPrototypeOf(b.buffer).constructor, ArrayBuffer);
-  }
-}
-
-if (typeof reportCompare === "function")
-    reportCompare(true, true);
deleted file mode 100644
--- a/js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const constructors = [
-    Int8Array,
-    Uint8Array,
-    Uint8ClampedArray,
-    Int16Array,
-    Uint16Array,
-    Int32Array,
-    Uint32Array,
-    Float32Array,
-    Float64Array
-];
-
-let logs = [];
-for (let ctor of constructors) {
-  let arr = new ctor([1, 2, 3, 4, 5, 6, 7, 8]);
-
-  let ctorObj = {};
-
-  let proxyProto = new Proxy({}, {
-    get(that, name) {
-      logs.push("get proto." + String(name));
-      if (name == "constructor")
-        return ctorObj;
-      throw new Error("unexpected prop access");
-    }
-  });
-
-  arr.buffer.constructor = {
-    get [Symbol.species]() {
-      logs.push("get @@species");
-      let C = new Proxy(function(...args) {
-        logs.push("call ctor");
-        return new ArrayBuffer(...args);
-      }, {
-        get(that, name) {
-          logs.push("get ctor." + String(name));
-          if (name == "prototype") {
-            return proxyProto;
-          }
-          throw new Error("unexpected prop access");
-        }
-      });
-      return C;
-    }
-  };
-
-  for (let ctor2 of constructors) {
-    logs.length = 0;
-    let arr2 = new ctor2(arr);
-    assertDeepEq(logs, ["get @@species", "get ctor.prototype"]);
-
-    logs.length = 0;
-    assertEq(Object.getPrototypeOf(arr2.buffer), proxyProto);
-    assertDeepEq(logs, []);
-
-    logs.length = 0;
-    assertEq(arr2.buffer.constructor, ctorObj);
-    assertDeepEq(logs, ["get proto.constructor"]);
-  }
-}
-
-if (typeof reportCompare === "function")
-    reportCompare(true, true);
--- a/js/src/vm/ArrayBufferObject-inl.h
+++ b/js/src/vm/ArrayBufferObject-inl.h
@@ -22,24 +22,16 @@ inline SharedMem<uint8_t*>
 ArrayBufferObjectMaybeShared::dataPointerEither()
 {
     ArrayBufferObjectMaybeShared* buf = this;
     if (buf->is<ArrayBufferObject>())
         return buf->as<ArrayBufferObject>().dataPointerShared();
     return buf->as<SharedArrayBufferObject>().dataPointerShared();
 }
 
-inline bool
-ArrayBufferObjectMaybeShared::isDetached() const
-{
-    if (this->is<ArrayBufferObject>())
-        return this->as<ArrayBufferObject>().isDetached();
-    return false;
-}
-
 inline uint32_t
 AnyArrayBufferByteLength(const ArrayBufferObjectMaybeShared* buf)
 {
     if (buf->is<ArrayBufferObject>())
         return buf->as<ArrayBufferObject>().byteLength();
     return buf->as<SharedArrayBufferObject>().byteLength();
 }
 
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -75,18 +75,16 @@ ArrayBufferObjectMaybeShared& AsAnyArray
 
 class ArrayBufferObjectMaybeShared : public NativeObject
 {
   public:
     uint32_t byteLength() {
         return AnyArrayBufferByteLength(this);
     }
 
-    inline bool isDetached() const;
-
     inline SharedMem<uint8_t*> dataPointerEither();
 };
 
 /*
  * ArrayBufferObject
  *
  * This class holds the underlying raw buffer that the various ArrayBufferViews
  * (eg DataViewObject, the TypedArrays, TypedObjects) access. It can be created
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -630,70 +630,59 @@ class TypedArrayObjectTemplate : public 
             JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
             return nullptr; // byteOffset + len is too big for the arraybuffer
         }
 
         return makeInstance(cx, buffer, byteOffset, len, proto);
     }
 
     static bool
-    maybeCreateArrayBuffer(JSContext* cx, uint32_t nelements, HandleObject nonDefaultProto,
-                           MutableHandle<ArrayBufferObject*> buffer)
+    maybeCreateArrayBuffer(JSContext* cx, uint32_t nelements, MutableHandle<ArrayBufferObject*> buffer)
     {
         static_assert(INLINE_BUFFER_LIMIT % sizeof(NativeType) == 0,
                       "ArrayBuffer inline storage shouldn't waste any space");
 
-        if (!nonDefaultProto && nelements <= INLINE_BUFFER_LIMIT / sizeof(NativeType)) {
+        if (nelements <= INLINE_BUFFER_LIMIT / sizeof(NativeType)) {
             // The array's data can be inline, and the buffer created lazily.
             return true;
         }
 
         if (nelements >= INT32_MAX / sizeof(NativeType)) {
             JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                                  JSMSG_NEED_DIET, "size and count");
             return false;
         }
 
-        ArrayBufferObject* buf = ArrayBufferObject::create(cx, nelements * sizeof(NativeType),
-                                                           nonDefaultProto);
+        ArrayBufferObject* buf = ArrayBufferObject::create(cx, nelements * sizeof(NativeType));
         if (!buf)
             return false;
 
         buffer.set(buf);
         return true;
     }
 
     static JSObject*
     fromLength(JSContext* cx, uint32_t nelements, HandleObject newTarget = nullptr)
     {
         RootedObject proto(cx);
         if (!GetPrototypeForInstance(cx, newTarget, &proto))
             return nullptr;
 
         Rooted<ArrayBufferObject*> buffer(cx);
-        if (!maybeCreateArrayBuffer(cx, nelements, nullptr, &buffer))
+        if (!maybeCreateArrayBuffer(cx, nelements, &buffer))
             return nullptr;
 
         return makeInstance(cx, buffer, 0, nelements, proto);
     }
 
-    static bool
-    AllocateArrayBuffer(JSContext* cx, HandleValue ctor, uint32_t elementLength,
-                        MutableHandle<ArrayBufferObject*> buffer);
-
-    static bool
-    CloneArrayBufferNoCopy(JSContext* cx, Handle<ArrayBufferObjectMaybeShared*> srcBuffer,
-                           bool isWrapped, uint32_t srcByteOffset,
-                           MutableHandle<ArrayBufferObject*> buffer);
-
     static JSObject*
     fromArray(JSContext* cx, HandleObject other, HandleObject newTarget = nullptr);
 
     static JSObject*
-    fromTypedArray(JSContext* cx, HandleObject other, bool isWrapped, HandleObject newTarget);
+    fromTypedArray(JSContext* cx, HandleObject other, HandleObject newTarget);
 
     static JSObject*
     fromObject(JSContext* cx, HandleObject other, HandleObject newTarget);
 
     static const NativeType
     getIndex(JSObject* obj, uint32_t index)
     {
         TypedArrayObject& tarray = obj->as<TypedArrayObject>();
@@ -724,228 +713,71 @@ typedef TypedArrayObjectTemplate<uint8_c
 } /* anonymous namespace */
 
 template<typename T>
 struct TypedArrayObject::OfType
 {
     typedef TypedArrayObjectTemplate<T> Type;
 };
 
-// ES 2016 draft Mar 25, 2016 24.1.1.1.
-template<typename T>
-/* static */ bool
-TypedArrayObjectTemplate<T>::AllocateArrayBuffer(JSContext* cx, HandleValue ctor,
-                                                 uint32_t elementLength,
-                                                 MutableHandle<ArrayBufferObject*> buffer)
-{
-    // ES 2016 draft Mar 25, 2016 24.1.1.1 step 1 (partially).
-    // ES 2016 draft Mar 25, 2016 9.1.14 steps 1-2.
-    MOZ_ASSERT(ctor.isObject());
-    RootedObject proto(cx);
-    RootedObject ctorObj(cx, &ctor.toObject());
-    if (!GetPrototypeFromConstructor(cx, ctorObj, &proto))
-        return false;
-    JSObject* arrayBufferProto = GlobalObject::getOrCreateArrayBufferPrototype(cx, cx->global());
-    if (!arrayBufferProto)
-        return false;
-    if (proto == arrayBufferProto)
-        proto = nullptr;
-
-    // ES 2016 draft Mar 25, 2016 24.1.1.1 steps 1 (remaining part), 2-6.
-    if (!maybeCreateArrayBuffer(cx, elementLength, proto, buffer))
-        return false;
-
-    return true;
-}
-
-static bool
-GetSpeciesConstructor(JSContext* cx, HandleObject obj, bool isWrapped, MutableHandleValue ctor)
-{
-    if (!isWrapped) {
-        if (!GlobalObject::ensureConstructor(cx, cx->global(), JSProto_ArrayBuffer))
-            return false;
-        RootedValue defaultCtor(cx, cx->global()->getConstructor(JSProto_ArrayBuffer));
-        if (!SpeciesConstructor(cx, obj, defaultCtor, ctor))
-            return false;
-
-        return true;
-    }
-
-    {
-        JSAutoCompartment ac(cx, obj);
-        if (!GlobalObject::ensureConstructor(cx, cx->global(), JSProto_ArrayBuffer))
-            return false;
-        RootedValue defaultCtor(cx, cx->global()->getConstructor(JSProto_ArrayBuffer));
-        if (!SpeciesConstructor(cx, obj, defaultCtor, ctor))
-            return false;
-    }
-
-    return JS_WrapValue(cx, ctor);
-}
-
-// ES 2016 draft Mar 25, 2016 24.1.1.4.
-template<typename T>
-/* static */ bool
-TypedArrayObjectTemplate<T>::CloneArrayBufferNoCopy(JSContext* cx,
-                                                    Handle<ArrayBufferObjectMaybeShared*> srcBuffer,
-                                                    bool isWrapped, uint32_t srcByteOffset,
-                                                    MutableHandle<ArrayBufferObject*> buffer)
-{
-    // Step 1 (skipped).
-
-    // Step 2.a.
-    RootedValue cloneCtor(cx);
-    if (!GetSpeciesConstructor(cx, srcBuffer, isWrapped, &cloneCtor))
-        return false;
-
-    // Step 2.b.
-    if (srcBuffer->isDetached()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
-        return false;
-    }
-
-    // Step 3 (skipped).
-
-    // Steps 4-5.
-    uint32_t srcLength = srcBuffer->byteLength();
-    MOZ_ASSERT(srcByteOffset <= srcLength);
-
-    // Step 6.
-    uint32_t cloneLength = srcLength - srcByteOffset;
-
-    // Step 7 (skipped).
-
-    // Steps 8.
-    MOZ_ASSERT(cloneLength % BYTES_PER_ELEMENT == 0);
-    if (!AllocateArrayBuffer(cx, cloneCtor, cloneLength / BYTES_PER_ELEMENT, buffer))
-        return false;
-
-    // Step 9.
-    if (srcBuffer->isDetached()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
-        return false;
-    }
-
-    // Steps 10-11 (done in caller).
-
-    // Step 12.
-    return true;
-}
-
 template<typename T>
 /* static */ JSObject*
 TypedArrayObjectTemplate<T>::fromArray(JSContext* cx, HandleObject other,
                                        HandleObject newTarget /* = nullptr */)
 {
     // Allow nullptr newTarget for FriendAPI methods, which don't care about
     // subclassing.
     if (other->is<TypedArrayObject>())
-        return fromTypedArray(cx, other, /* wrapped= */ false, newTarget);
-
-    if (other->is<WrapperObject>() && UncheckedUnwrap(other)->is<TypedArrayObject>())
-        return fromTypedArray(cx, other, /* wrapped= */ true, newTarget);
+        return fromTypedArray(cx, other, newTarget);
 
     return fromObject(cx, other, newTarget);
 }
 
 // ES 2016 draft Mar 25, 2016 22.2.4.3.
 template<typename T>
 /* static */ JSObject*
-TypedArrayObjectTemplate<T>::fromTypedArray(JSContext* cx, HandleObject other, bool isWrapped,
+TypedArrayObjectTemplate<T>::fromTypedArray(JSContext* cx, HandleObject other,
                                             HandleObject newTarget)
 {
     // Step 1.
-    MOZ_ASSERT_IF(!isWrapped, other->is<TypedArrayObject>());
-    MOZ_ASSERT_IF(isWrapped,
-                  other->is<WrapperObject>() &&
-                  UncheckedUnwrap(other)->is<TypedArrayObject>());
+    MOZ_ASSERT(other->is<TypedArrayObject>());
 
     // Step 2 (done in caller).
 
     // Step 4 (partially).
     RootedObject proto(cx);
     if (!GetPrototypeForInstance(cx, newTarget, &proto))
         return nullptr;
 
     // Step 5.
-    Rooted<TypedArrayObject*> srcArray(cx);
-    if (!isWrapped) {
-        srcArray = &other->as<TypedArrayObject>();
-        if (!TypedArrayObject::ensureHasBuffer(cx, srcArray))
-            return nullptr;
-    } else {
-        RootedObject unwrapped(cx, CheckedUnwrap(other));
-        if (!unwrapped) {
-            JS_ReportError(cx, "Permission denied to access object");
-            return nullptr;
-        }
+    Rooted<TypedArrayObject*> srcArray(cx, &other->as<TypedArrayObject>());
 
-        JSAutoCompartment ac(cx, unwrapped);
-
-        srcArray = &unwrapped->as<TypedArrayObject>();
-        if (!TypedArrayObject::ensureHasBuffer(cx, srcArray))
-            return nullptr;
-    }
-
-    // Step 6.
-    Rooted<ArrayBufferObjectMaybeShared*> srcData(cx, srcArray->bufferEither());
-
-    // Step 7.
-    if (srcData->isDetached()) {
+    // Steps 6-7.
+    if (srcArray->hasDetachedBuffer()) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
         return nullptr;
     }
 
     // Steps 10.
     uint32_t elementLength = srcArray->length();
 
-    // Steps 11-12.
-    Scalar::Type srcType = srcArray->type();
-
-    // Step 13 (skipped).
-
-    // Step 14.
-    uint32_t srcByteOffset = srcArray->byteOffset();
-
-    // Steps 15-16 (skipped).
-    // Our AllocateArrayBuffer receives elementLength instead of byteLength.
-
-    // Steps 8-9, 17.
+    // Steps 8-9, 11-18.
     Rooted<ArrayBufferObject*> buffer(cx);
-    if (ArrayTypeID() == srcType) {
-        // Step 17.a.
-        if (!CloneArrayBufferNoCopy(cx, srcData, isWrapped, srcByteOffset, &buffer))
-            return nullptr;
-    } else {
-        // Step 18.a.
-        RootedValue bufferCtor(cx);
-        if (!GetSpeciesConstructor(cx, srcData, isWrapped, &bufferCtor))
-            return nullptr;
+    if (!maybeCreateArrayBuffer(cx, elementLength, &buffer))
+        return nullptr;
 
-        // Step 18.b.
-        if (!AllocateArrayBuffer(cx, bufferCtor, elementLength, &buffer))
-            return nullptr;
-
-        // Step 18.c.
-        if (srcArray->hasDetachedBuffer()) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
-            return nullptr;
-        }
-    }
-
-    // Steps 3, 4 (remaining part), 19-22.
+    // Steps 3, 4 (remaining part), 19-23.
     Rooted<TypedArrayObject*> obj(cx, makeInstance(cx, buffer, 0, elementLength, proto));
     if (!obj)
         return nullptr;
 
     // Step 18.d-g or 24.1.1.4 step 11.
     if (!TypedArrayMethods<TypedArrayObject>::setFromTypedArray(cx, obj, srcArray))
         return nullptr;
 
-    // Step 23.
     return obj;
 }
 
 // FIXME: This is not compatible with TypedArrayFrom in the spec
 // (ES 2016 draft Mar 25, 2016 22.2.4.4 and 22.2.2.1.1)
 // We should handle iterator protocol (bug 1232266).
 template<typename T>
 /* static */ JSObject*
@@ -953,17 +785,17 @@ TypedArrayObjectTemplate<T>::fromObject(
 {
     RootedObject proto(cx);
     Rooted<ArrayBufferObject*> buffer(cx);
     uint32_t len;
     if (!GetLengthProperty(cx, other, &len))
         return nullptr;
     if (!GetPrototypeForInstance(cx, newTarget, &proto))
         return nullptr;
-    if (!maybeCreateArrayBuffer(cx, len, nullptr, &buffer))
+    if (!maybeCreateArrayBuffer(cx, len, &buffer))
         return nullptr;
 
     Rooted<TypedArrayObject*> obj(cx, makeInstance(cx, buffer, 0, len, proto));
     if (!obj)
         return nullptr;
 
     if (!TypedArrayMethods<TypedArrayObject>::setFromNonTypedArray(cx, obj, other, len))
         return nullptr;