Title: [196950] trunk/Source/_javascript_Core
Revision
196950
Author
keith_mil...@apple.com
Date
2016-02-22 12:07:50 -0800 (Mon, 22 Feb 2016)

Log Message

Use Symbol.species in the builtin TypedArray.prototype functions
https://bugs.webkit.org/show_bug.cgi?id=153384

Reviewed by Geoffrey Garen.

This patch adds the use of species constructors to the TypedArray.prototype map and filter
functions. It also adds a new private function typedArrayGetOriginalConstructor that
returns the TypedArray constructor used to originally create a TypedArray instance.

There are no ES6 tests to update for this patch as species creation for these functions is
not tested in the compatibility table.

* builtins/TypedArrayPrototype.js:
(map):
(filter):
* bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
* bytecode/BytecodeIntrinsicRegistry.h:
* runtime/CommonIdentifiers.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::typedArrayConstructor):
* runtime/JSTypedArrayViewPrototype.cpp:
(JSC::typedArrayViewPrivateFuncGetOriginalConstructor):
* runtime/JSTypedArrayViewPrototype.h:
* tests/stress/typedarray-filter.js:
(subclasses.typedArrays.map):
(prototype.accept):
(testSpecies):
(accept):
(forEach):
(subclasses.forEach):
(testSpeciesRemoveConstructor):
* tests/stress/typedarray-map.js:
(subclasses.typedArrays.map):
(prototype.id):
(testSpecies):
(id):
(forEach):
(subclasses.forEach):
(testSpeciesRemoveConstructor):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (196949 => 196950)


--- trunk/Source/_javascript_Core/ChangeLog	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-02-22 20:07:50 UTC (rev 196950)
@@ -1,5 +1,51 @@
 2016-02-22  Keith Miller  <keith_mil...@apple.com>
 
+        Use Symbol.species in the builtin TypedArray.prototype functions
+        https://bugs.webkit.org/show_bug.cgi?id=153384
+
+        Reviewed by Geoffrey Garen.
+
+        This patch adds the use of species constructors to the TypedArray.prototype map and filter
+        functions. It also adds a new private function typedArrayGetOriginalConstructor that
+        returns the TypedArray constructor used to originally create a TypedArray instance.
+
+        There are no ES6 tests to update for this patch as species creation for these functions is
+        not tested in the compatibility table.
+
+        * builtins/TypedArrayPrototype.js:
+        (map):
+        (filter):
+        * bytecode/BytecodeIntrinsicRegistry.cpp:
+        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
+        * bytecode/BytecodeIntrinsicRegistry.h:
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::typedArrayConstructor):
+        * runtime/JSTypedArrayViewPrototype.cpp:
+        (JSC::typedArrayViewPrivateFuncGetOriginalConstructor):
+        * runtime/JSTypedArrayViewPrototype.h:
+        * tests/stress/typedarray-filter.js:
+        (subclasses.typedArrays.map):
+        (prototype.accept):
+        (testSpecies):
+        (accept):
+        (forEach):
+        (subclasses.forEach):
+        (testSpeciesRemoveConstructor):
+        * tests/stress/typedarray-map.js:
+        (subclasses.typedArrays.map):
+        (prototype.id):
+        (testSpecies):
+        (id):
+        (forEach):
+        (subclasses.forEach):
+        (testSpeciesRemoveConstructor):
+
+2016-02-22  Keith Miller  <keith_mil...@apple.com>
+
         Builtins that should not rely on iteration do.
         https://bugs.webkit.org/show_bug.cgi?id=154475
 

Modified: trunk/Source/_javascript_Core/builtins/TypedArrayPrototype.js (196949 => 196950)


--- trunk/Source/_javascript_Core/builtins/TypedArrayPrototype.js	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/builtins/TypedArrayPrototype.js	2016-02-22 20:07:50 UTC (rev 196950)
@@ -233,8 +233,23 @@
         throw new @TypeError("TypedArray.prototype.map callback must be a function");
 
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
-    // FIXME: This should be a species constructor.
-    var result = new this.constructor(length);
+
+    // Do species construction
+    var constructor = this.constructor;
+    var result;
+    if (constructor === @undefined)
+        result = new (@typedArrayGetOriginalConstructor(this))(length);
+    else {
+        var speciesConstructor = @Object(constructor)[@symbolSpecies];
+        if (speciesConstructor === null || speciesConstructor === @undefined)
+            result = new (@typedArrayGetOriginalConstructor(this))(length);
+        else {
+            result = new speciesConstructor(length);
+            // typedArrayLength throws if it doesn't get a view.
+            @typedArrayLength(result);
+        }
+    }
+
     for (var i = 0; i < length; i++) {
         var mappedValue = callback.@call(thisArg, this[i], i, this);
         result[i] = mappedValue;
@@ -252,7 +267,6 @@
         throw new @TypeError("TypedArray.prototype.filter callback must be a function");
 
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
-
     var kept = [];
 
     for (var i = 0; i < length; i++) {
@@ -261,8 +275,21 @@
             kept.@push(value);
     }
 
-    // FIXME: This should be a species constructor.
-    var result = new this.constructor(kept.length);
+    var constructor = this.constructor;
+    var result;
+    var resultLength = kept.length;
+    if (constructor === @undefined)
+        result = new (@typedArrayGetOriginalConstructor(this))(resultLength);
+    else {
+        var speciesConstructor = @Object(constructor)[@symbolSpecies];
+        if (speciesConstructor === null || speciesConstructor === @undefined)
+            result = new (@typedArrayGetOriginalConstructor(this))(resultLength);
+        else {
+            result = new speciesConstructor(resultLength);
+            // typedArrayLength throws if it doesn't get a view.
+            @typedArrayLength(result);
+        }
+    }
 
     for (var i = 0; i < kept.length; i++)
         result[i] = kept[i];

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp (196949 => 196950)


--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp	2016-02-22 20:07:50 UTC (rev 196950)
@@ -52,6 +52,7 @@
     m_promiseStateRejected.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Rejected)));
     m_symbolIterator.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->iteratorSymbol.impl())));
     m_symbolSearch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->searchSymbol.impl())));
+    m_symbolSpecies.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->speciesSymbol.impl())));
 }
 
 BytecodeIntrinsicNode::EmitterType BytecodeIntrinsicRegistry::lookup(const Identifier& ident) const

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h (196949 => 196950)


--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h	2016-02-22 20:07:50 UTC (rev 196950)
@@ -53,7 +53,8 @@
     macro(promiseStateFulfilled) \
     macro(promiseStateRejected) \
     macro(symbolIterator) \
-    macro(symbolSearch)
+    macro(symbolSearch) \
+    macro(symbolSpecies)
 
 class BytecodeIntrinsicRegistry {
     WTF_MAKE_NONCOPYABLE(BytecodeIntrinsicRegistry);

Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (196949 => 196950)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2016-02-22 20:07:50 UTC (rev 196950)
@@ -320,6 +320,7 @@
     macro(TypeError) \
     macro(typedArrayLength) \
     macro(typedArraySort) \
+    macro(typedArrayGetOriginalConstructor) \
     macro(BuiltinLog) \
     macro(homeObject) \
     macro(getTemplateObject) \

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (196949 => 196950)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2016-02-22 20:07:50 UTC (rev 196950)
@@ -483,32 +483,31 @@
     JSTypedArrayViewConstructor* typedArraySuperConstructor = JSTypedArrayViewConstructor::create(vm, this, JSTypedArrayViewConstructor::createStructure(vm, this, m_functionPrototype.get()), typedArrayProto, speciesGetterSetter);
     typedArrayProto->putDirectWithoutTransition(vm, vm.propertyNames->constructor, typedArraySuperConstructor, DontEnum);
 
-    std::array<InternalFunction*, NUMBER_OF_TYPED_ARRAY_TYPES> typedArrayConstructors;
-    typedArrayConstructors[toIndex(TypeInt8)] = JSInt8ArrayConstructor::create(vm, this, JSInt8ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeInt8)].prototype.get(), ASCIILiteral("Int8Array"), typedArrayConstructorAllocateInt8ArrayCodeGenerator(vm));
-    typedArrayConstructors[toIndex(TypeInt16)] = JSInt16ArrayConstructor::create(vm, this, JSInt16ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeInt16)].prototype.get(), ASCIILiteral("Int16Array"), typedArrayConstructorAllocateInt16ArrayCodeGenerator(vm));
-    typedArrayConstructors[toIndex(TypeInt32)] = JSInt32ArrayConstructor::create(vm, this, JSInt32ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeInt32)].prototype.get(), ASCIILiteral("Int32Array"), typedArrayConstructorAllocateInt32ArrayCodeGenerator(vm));
-    typedArrayConstructors[toIndex(TypeUint8)] = JSUint8ArrayConstructor::create(vm, this, JSUint8ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeUint8)].prototype.get(), ASCIILiteral("Uint8Array"), typedArrayConstructorAllocateUint8ArrayCodeGenerator(vm));
-    typedArrayConstructors[toIndex(TypeUint8Clamped)] = JSUint8ClampedArrayConstructor::create(vm, this, JSUint8ClampedArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeUint8Clamped)].prototype.get(), ASCIILiteral("Uint8ClampedArray"), typedArrayConstructorAllocateUint8ClampedArrayCodeGenerator(vm));
-    typedArrayConstructors[toIndex(TypeUint16)] = JSUint16ArrayConstructor::create(vm, this, JSUint16ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeUint16)].prototype.get(), ASCIILiteral("Uint16Array"), typedArrayConstructorAllocateUint16ArrayCodeGenerator(vm));
-    typedArrayConstructors[toIndex(TypeUint32)] = JSUint32ArrayConstructor::create(vm, this, JSUint32ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeUint32)].prototype.get(), ASCIILiteral("Uint32Array"), typedArrayConstructorAllocateUint32ArrayCodeGenerator(vm));
-    typedArrayConstructors[toIndex(TypeFloat32)] = JSFloat32ArrayConstructor::create(vm, this, JSFloat32ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeFloat32)].prototype.get(), ASCIILiteral("Float32Array"), typedArrayConstructorAllocateFloat32ArrayCodeGenerator(vm));
-    typedArrayConstructors[toIndex(TypeFloat64)] = JSFloat64ArrayConstructor::create(vm, this, JSFloat64ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeFloat64)].prototype.get(), ASCIILiteral("Float64Array"), typedArrayConstructorAllocateFloat64ArrayCodeGenerator(vm));
-    typedArrayConstructors[toIndex(TypeDataView)] = JSDataViewConstructor::create(vm, this, JSDataViewConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeDataView)].prototype.get(), ASCIILiteral("DataView"), nullptr);
+    m_typedArrays[toIndex(TypeInt8)].constructor.set(vm , this, JSInt8ArrayConstructor::create(vm, this, JSInt8ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeInt8)].prototype.get(), ASCIILiteral("Int8Array"), typedArrayConstructorAllocateInt8ArrayCodeGenerator(vm)));
+    m_typedArrays[toIndex(TypeInt16)].constructor.set(vm, this, JSInt16ArrayConstructor::create(vm, this, JSInt16ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeInt16)].prototype.get(), ASCIILiteral("Int16Array"), typedArrayConstructorAllocateInt16ArrayCodeGenerator(vm)));
+    m_typedArrays[toIndex(TypeInt32)].constructor.set(vm, this, JSInt32ArrayConstructor::create(vm, this, JSInt32ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeInt32)].prototype.get(), ASCIILiteral("Int32Array"), typedArrayConstructorAllocateInt32ArrayCodeGenerator(vm)));
+    m_typedArrays[toIndex(TypeUint8)].constructor.set(vm, this, JSUint8ArrayConstructor::create(vm, this, JSUint8ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeUint8)].prototype.get(), ASCIILiteral("Uint8Array"), typedArrayConstructorAllocateUint8ArrayCodeGenerator(vm)));
+    m_typedArrays[toIndex(TypeUint8Clamped)].constructor.set(vm, this, JSUint8ClampedArrayConstructor::create(vm, this, JSUint8ClampedArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeUint8Clamped)].prototype.get(), ASCIILiteral("Uint8ClampedArray"), typedArrayConstructorAllocateUint8ClampedArrayCodeGenerator(vm)));
+    m_typedArrays[toIndex(TypeUint16)].constructor.set(vm, this, JSUint16ArrayConstructor::create(vm, this, JSUint16ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeUint16)].prototype.get(), ASCIILiteral("Uint16Array"), typedArrayConstructorAllocateUint16ArrayCodeGenerator(vm)));
+    m_typedArrays[toIndex(TypeUint32)].constructor.set(vm, this, JSUint32ArrayConstructor::create(vm, this, JSUint32ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeUint32)].prototype.get(), ASCIILiteral("Uint32Array"), typedArrayConstructorAllocateUint32ArrayCodeGenerator(vm)));
+    m_typedArrays[toIndex(TypeFloat32)].constructor.set(vm, this, JSFloat32ArrayConstructor::create(vm, this, JSFloat32ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeFloat32)].prototype.get(), ASCIILiteral("Float32Array"), typedArrayConstructorAllocateFloat32ArrayCodeGenerator(vm)));
+    m_typedArrays[toIndex(TypeFloat64)].constructor.set(vm, this, JSFloat64ArrayConstructor::create(vm, this, JSFloat64ArrayConstructor::createStructure(vm, this, typedArraySuperConstructor), m_typedArrays[toIndex(TypeFloat64)].prototype.get(), ASCIILiteral("Float64Array"), typedArrayConstructorAllocateFloat64ArrayCodeGenerator(vm)));
+    m_typedArrays[toIndex(TypeDataView)].constructor.set(vm, this, JSDataViewConstructor::create(vm, this, JSDataViewConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeDataView)].prototype.get(), ASCIILiteral("DataView"), nullptr));
     
     for (unsigned typedArrayIndex = NUMBER_OF_TYPED_ARRAY_TYPES; typedArrayIndex--;) {
-        m_typedArrays[typedArrayIndex].prototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, typedArrayConstructors[typedArrayIndex], DontEnum);
-        putDirectWithoutTransition(vm, Identifier::fromString(exec, typedArrayConstructors[typedArrayIndex]->name(exec)), typedArrayConstructors[typedArrayIndex], DontEnum);
+        m_typedArrays[typedArrayIndex].prototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, m_typedArrays[typedArrayIndex].constructor.get(), DontEnum);
+        putDirectWithoutTransition(vm, Identifier::fromString(exec, m_typedArrays[typedArrayIndex].constructor.get()->name(exec)), m_typedArrays[typedArrayIndex].constructor.get(), DontEnum);
     }
 
-    putDirectWithoutTransition(vm, vm.propertyNames->Int8ArrayPrivateName, typedArrayConstructors[toIndex(TypeInt8)], DontEnum);
-    putDirectWithoutTransition(vm, vm.propertyNames->Int16ArrayPrivateName, typedArrayConstructors[toIndex(TypeInt16)], DontEnum);
-    putDirectWithoutTransition(vm, vm.propertyNames->Int32ArrayPrivateName, typedArrayConstructors[toIndex(TypeInt32)], DontEnum);
-    putDirectWithoutTransition(vm, vm.propertyNames->Uint8ArrayPrivateName, typedArrayConstructors[toIndex(TypeUint8)], DontEnum);
-    putDirectWithoutTransition(vm, vm.propertyNames->Uint8ClampedArrayPrivateName, typedArrayConstructors[toIndex(TypeUint8Clamped)], DontEnum);
-    putDirectWithoutTransition(vm, vm.propertyNames->Uint16ArrayPrivateName, typedArrayConstructors[toIndex(TypeUint16)], DontEnum);
-    putDirectWithoutTransition(vm, vm.propertyNames->Uint32ArrayPrivateName, typedArrayConstructors[toIndex(TypeUint32)], DontEnum);
-    putDirectWithoutTransition(vm, vm.propertyNames->Float32ArrayPrivateName, typedArrayConstructors[toIndex(TypeFloat32)], DontEnum);
-    putDirectWithoutTransition(vm, vm.propertyNames->Float64ArrayPrivateName, typedArrayConstructors[toIndex(TypeFloat64)], DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->Int8ArrayPrivateName, m_typedArrays[toIndex(TypeInt8)].constructor.get(), DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->Int16ArrayPrivateName, m_typedArrays[toIndex(TypeInt16)].constructor.get(), DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->Int32ArrayPrivateName, m_typedArrays[toIndex(TypeInt32)].constructor.get(), DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->Uint8ArrayPrivateName, m_typedArrays[toIndex(TypeUint8)].constructor.get(), DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->Uint8ClampedArrayPrivateName, m_typedArrays[toIndex(TypeUint8Clamped)].constructor.get(), DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->Uint16ArrayPrivateName, m_typedArrays[toIndex(TypeUint16)].constructor.get(), DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->Uint32ArrayPrivateName, m_typedArrays[toIndex(TypeUint32)].constructor.get(), DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->Float32ArrayPrivateName, m_typedArrays[toIndex(TypeFloat32)].constructor.get(), DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->Float64ArrayPrivateName, m_typedArrays[toIndex(TypeFloat64)].constructor.get(), DontEnum);
 
     m_moduleLoader.set(vm, this, ModuleLoaderObject::create(vm, this, ModuleLoaderObject::createStructure(vm, this, m_objectPrototype.get())));
     if (Options::exposeInternalModuleLoader())
@@ -525,6 +524,7 @@
     JSFunction* privateFuncToLength = JSFunction::createBuiltinFunction(vm, globalObjectToLengthCodeGenerator(vm), this);
     JSFunction* privateFuncToInteger = JSFunction::createBuiltinFunction(vm, globalObjectToIntegerCodeGenerator(vm), this);
     JSFunction* privateFuncTypedArrayLength = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncLength);
+    JSFunction* privateFuncTypedArrayGetOriginalConstructor = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncGetOriginalConstructor);
     JSFunction* privateFuncTypedArraySort = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncSort);
     JSFunction* privateFuncIsBoundFunction = JSFunction::create(vm, this, 0, String(), isBoundFunction);
     JSFunction* privateFuncHasInstanceBoundFunction = JSFunction::create(vm, this, 0, String(), hasInstanceBoundFunction);
@@ -542,6 +542,7 @@
         GlobalPropertyInfo(vm.propertyNames->RangeErrorPrivateName, m_rangeErrorConstructor.get(), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->TypeErrorPrivateName, m_typeErrorConstructor.get(), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->typedArrayLengthPrivateName, privateFuncTypedArrayLength, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->typedArrayGetOriginalConstructorPrivateName, privateFuncTypedArrayGetOriginalConstructor, DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->typedArraySortPrivateName, privateFuncTypedArraySort, DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->isBoundFunctionPrivateName, privateFuncIsBoundFunction, DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->hasInstanceBoundFunctionPrivateName, privateFuncHasInstanceBoundFunction, DontEnum | DontDelete | ReadOnly),
@@ -916,6 +917,7 @@
 
     for (unsigned i = NUMBER_OF_TYPED_ARRAY_TYPES; i--;) {
         visitor.append(&thisObject->m_typedArrays[i].prototype);
+        visitor.append(&thisObject->m_typedArrays[i].constructor);
         visitor.append(&thisObject->m_typedArrays[i].structure);
     }
 }

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (196949 => 196950)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2016-02-22 20:07:50 UTC (rev 196950)
@@ -293,6 +293,7 @@
 
     struct TypedArrayData {
         WriteBarrier<JSObject> prototype;
+        WriteBarrier<InternalFunction> constructor;
         WriteBarrier<Structure> structure;
     };
     
@@ -581,6 +582,11 @@
         return typedArrayStructure(type) == structure;
     }
 
+    JSObject* typedArrayConstructor(TypedArrayType type) const
+    {
+        return m_typedArrays[toIndex(type)].constructor.get();
+    }
+
     JSCell* actualPointerFor(Special::Pointer pointer)
     {
         ASSERT(pointer < Special::TableSize);

Modified: trunk/Source/_javascript_Core/runtime/JSTypedArrayViewPrototype.cpp (196949 => 196950)


--- trunk/Source/_javascript_Core/runtime/JSTypedArrayViewPrototype.cpp	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/runtime/JSTypedArrayViewPrototype.cpp	2016-02-22 20:07:50 UTC (rev 196950)
@@ -74,6 +74,14 @@
     return JSValue::encode(jsNumber(thisObject->length()));
 }
 
+EncodedJSValue JSC_HOST_CALL typedArrayViewPrivateFuncGetOriginalConstructor(ExecState* exec)
+{
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    TypedArrayType type = exec->uncheckedArgument(0).getObject()->classInfo()->typedArrayStorageType;
+    ASSERT(isTypedView(type));
+    return JSValue::encode(globalObject->typedArrayConstructor(type));
+}
+
 EncodedJSValue JSC_HOST_CALL typedArrayViewPrivateFuncSort(ExecState* exec)
 {
     JSValue thisValue = exec->argument(0);

Modified: trunk/Source/_javascript_Core/runtime/JSTypedArrayViewPrototype.h (196949 => 196950)


--- trunk/Source/_javascript_Core/runtime/JSTypedArrayViewPrototype.h	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/runtime/JSTypedArrayViewPrototype.h	2016-02-22 20:07:50 UTC (rev 196950)
@@ -48,6 +48,7 @@
 
 EncodedJSValue JSC_HOST_CALL typedArrayViewPrivateFuncSort(ExecState*);
 EncodedJSValue JSC_HOST_CALL typedArrayViewPrivateFuncLength(ExecState*);
+EncodedJSValue JSC_HOST_CALL typedArrayViewPrivateFuncGetOriginalConstructor(ExecState*);
 
     
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/tests/stress/typedarray-filter.js (196949 => 196950)


--- trunk/Source/_javascript_Core/tests/stress/typedarray-filter.js	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/tests/stress/typedarray-filter.js	2016-02-22 20:07:50 UTC (rev 196950)
@@ -48,4 +48,56 @@
 shouldThrow("testPrototypeFunction('filter', '(null)', [12, 15, 10, 13, 44], false)", "'TypeError: TypedArray.prototype.filter callback must be a function'");
 shouldThrow("testPrototypeFunction('filter', '()', [12, 15, 10, 13, 44], false)", "'TypeError: TypedArray.prototype.filter callback must be a function'");
 debug("");
+
+debug("6.0 Symbol.species Test");
+subclasses = typedArrays.map(function(constructor) { return class extends constructor { } } );
+
+function accept() { return true; }
+
+function testSpecies(array, constructor) {
+    let newArray = array.filter(accept);
+    return newArray instanceof constructor;
+}
+
+shouldBeTrue("forEachTypedArray(subclasses, testSpecies)");
+
+Foo = class extends Int32Array { }
+subclasses.forEach(function(constructor) { Object.defineProperty(constructor, Symbol.species, { value:Foo, writable:true }); });
+function testSpeciesWithFoo(array, constructor) {
+    let newArray = array.filter(accept);
+    return newArray instanceof Foo;
+}
+shouldBeTrue("forEachTypedArray(subclasses, testSpeciesWithFoo)");
+debug("");
+
+debug("6.2 Symbol.species Test throws");
+subclasses.forEach(function(constructor) { constructor[Symbol.species] = 1; });
+shouldThrow("forEachTypedArray(subclasses, testSpecies)");
+
+subclasses.forEach(function(constructor) { constructor[Symbol.species] = Array; });
+shouldThrow("forEachTypedArray(subclasses, testSpecies)");
+debug("");
+
+debug("6.2 Symbol.species Test with Defaults");
+subclasses.forEach(function(constructor) { constructor[Symbol.species] = null; });
+function testSpeciesIsDefault(array, constructor) {
+    let newArray = array.filter(accept);
+    let defaultConstructor = typedArrays[subclasses.indexOf(constructor)];
+    return newArray instanceof defaultConstructor;
+}
+
+shouldBeTrue("forEachTypedArray(subclasses, testSpeciesIsDefault)");
+
+subclasses.forEach(function(constructor) { constructor[Symbol.species] = undefined; });
+shouldBeTrue("forEachTypedArray(subclasses, testSpeciesIsDefault)");
+
+subclasses = typedArrays.map(function(constructor) { return class extends constructor { } } );
+function testSpeciesRemoveConstructor(array, constructor) {
+    array.constructor = undefined;
+    let newArray = array.filter(accept);
+    let defaultConstructor = typedArrays[subclasses.indexOf(constructor)];
+    return newArray instanceof defaultConstructor;
+}
+
+shouldBeTrue("forEachTypedArray(subclasses, testSpeciesRemoveConstructor)");
 finishJSTest();

Modified: trunk/Source/_javascript_Core/tests/stress/typedarray-map.js (196949 => 196950)


--- trunk/Source/_javascript_Core/tests/stress/typedarray-map.js	2016-02-22 19:43:01 UTC (rev 196949)
+++ trunk/Source/_javascript_Core/tests/stress/typedarray-map.js	2016-02-22 20:07:50 UTC (rev 196950)
@@ -48,4 +48,55 @@
 shouldThrow("testPrototypeFunction('map', '(null)', [12, 15, 10, 13, 44], false)", "'TypeError: TypedArray.prototype.map callback must be a function'");
 shouldThrow("testPrototypeFunction('map', '()', [12, 15, 10, 13, 44], false)", "'TypeError: TypedArray.prototype.map callback must be a function'");
 debug("");
+
+debug("6.0 Symbol.species Test");
+subclasses = typedArrays.map(function(constructor) { return class extends constructor { } } );
+
+function id(x) { return x; }
+
+function testSpecies(array, constructor) {
+    let newArray = array.map(id);
+    return newArray instanceof constructor;
+}
+shouldBeTrue("forEachTypedArray(subclasses, testSpecies)");
+
+Foo = class extends Int32Array { }
+subclasses.forEach(function(constructor) { Object.defineProperty(constructor, Symbol.species, { value:Foo, writable:true }); });
+function testSpeciesWithFoo(array, constructor) {
+    let newArray = array.map(id);
+    return newArray instanceof Foo;
+}
+shouldBeTrue("forEachTypedArray(subclasses, testSpeciesWithFoo)");
+debug("");
+
+debug("6.1 Symbol.species Test throws");
+subclasses.forEach(function(constructor) { Object.defineProperty(constructor, Symbol.species, { value:1, writable:true }); });
+shouldThrow("forEachTypedArray(subclasses, testSpecies)");
+
+subclasses.forEach(function(constructor) { constructor[Symbol.species] = Array; });
+shouldThrow("forEachTypedArray(subclasses, testSpecies)");
+debug("");
+
+debug("6.2 Symbol.species Test with Defaults");
+subclasses.forEach(function(constructor) { constructor[Symbol.species] = null; });
+function testSpeciesIsDefault(array, constructor) {
+    let newArray = array.map(id);
+    let defaultConstructor = typedArrays[subclasses.indexOf(constructor)];
+    return newArray instanceof defaultConstructor;
+}
+
+shouldBeTrue("forEachTypedArray(subclasses, testSpeciesIsDefault)");
+
+subclasses.forEach(function(constructor) { constructor[Symbol.species] = undefined; });
+shouldBeTrue("forEachTypedArray(subclasses, testSpeciesIsDefault)");
+
+subclasses = typedArrays.map(function(constructor) { return class extends constructor { } } );
+function testSpeciesRemoveConstructor(array, constructor) {
+    array.constructor = undefined;
+    let newArray = array.map(id);
+    let defaultConstructor = typedArrays[subclasses.indexOf(constructor)];
+    return newArray instanceof defaultConstructor;
+}
+
+shouldBeTrue("forEachTypedArray(subclasses, testSpeciesRemoveConstructor)");
 finishJSTest();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to