Bug 1165053 - Part 2: Implement %TypedArray%[@@species] getter and ArrayBuffer[@@species] getter. r=evilpie
authorTooru Fujisawa <arai_a@mac.com>
Sun, 20 Dec 2015 19:14:44 +0900
changeset 330041 5cdf65882fe2279e713b578ca319e0862072a491
parent 330040 38d7887d6f237ea38887bb076d9cdad5d86a54c6
child 330042 93b858a8ec08f0e6e14dd595d5010614a5ea480c
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs1165053
milestone48.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 1165053 - Part 2: Implement %TypedArray%[@@species] getter and ArrayBuffer[@@species] getter. r=evilpie
js/src/builtin/TypedArray.js
js/src/builtin/Utilities.js
js/src/tests/ecma_6/Symbol/species.js
js/src/vm/ArrayBufferObject.cpp
js/src/vm/ArrayBufferObject.h
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
--- a/js/src/builtin/TypedArray.js
+++ b/js/src/builtin/TypedArray.js
@@ -1303,16 +1303,22 @@ function TypedArrayStaticOf(/*...items*/
     // Steps 6-7.
     for (var k = 0; k < len; k++)
         newObj[k] = items[k]
 
     // Step 8.
     return newObj;
 }
 
+// ES 2016 draft Mar 25, 2016 22.2.2.4.
+function TypedArraySpecies() {
+    // Step 1.
+    return this;
+}
+
 // ES 2016 draft Mar 25, 2016 24.1.4.3.
 function ArrayBufferSlice(start, end) {
     // Step 1.
     var O = this;
 
     // Steps 2-3,
     // This function is not generic.
     if (!IsObject(O) || !IsArrayBuffer(O)) {
@@ -1392,8 +1398,14 @@ function IsDetachedBufferThis() {
   return IsDetachedBuffer(this);
 }
 
 function ArrayBufferStaticSlice(buf, start, end) {
     if (arguments.length < 1)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'ArrayBuffer.slice');
     return callFunction(ArrayBufferSlice, buf, start, end);
 }
+
+// ES 2016 draft Mar 25, 2016 24.1.3.3.
+function ArrayBufferSpecies() {
+    // Step 1.
+    return this;
+}
--- a/js/src/builtin/Utilities.js
+++ b/js/src/builtin/Utilities.js
@@ -162,44 +162,44 @@ function GetBuiltinConstructor(builtinNa
     assert(ctor, `No builtin with name "${builtinName}" found`);
     return ctor;
 }
 
 function GetBuiltinPrototype(builtinName) {
     return (_builtinCtorsCache[builtinName] || GetBuiltinConstructor(builtinName)).prototype;
 }
 
-// ES6 draft 20150317 7.3.20.
+// ES 2016 draft Mar 25, 2016 7.3.20.
 function SpeciesConstructor(obj, defaultConstructor) {
     // Step 1.
     assert(IsObject(obj), "not passed an object");
 
-    // Steps 2-3.
+    // Step 2.
     var ctor = obj.constructor;
 
-    // Step 4.
+    // Step 3.
     if (ctor === undefined)
         return defaultConstructor;
 
-    // Step 5.
+    // Step 4.
     if (!IsObject(ctor))
         ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, "object's 'constructor' property");
 
-    // Steps 6-7.
+    // Steps 5.
     var s = ctor[std_species];
 
-    // Step 8.
+    // Step 6.
     if (s === undefined || s === null)
         return defaultConstructor;
 
-    // Step 9.
+    // Step 7.
     if (IsConstructor(s))
         return s;
 
-    // Step 10.
+    // Step 8.
     ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, "@@species property of object's constructor");
 }
 
 function GetTypeError(msg) {
     try {
         FUN_APPLY(ThrowTypeError, undefined, arguments);
     } catch (e) {
         return e;
--- a/js/src/tests/ecma_6/Symbol/species.js
+++ b/js/src/tests/ecma_6/Symbol/species.js
@@ -1,18 +1,26 @@
 var BUGNUMBER = 1131043;
 var summary = "Implement @@species getter for builtin types";
 
 print(BUGNUMBER + ": " + summary);
 
-for (var C of [Map, Set]) {
+var TypedArray = Object.getPrototypeOf(Int8Array);
+
+for (var C of [Map, Set,
+               Int8Array, Uint8Array, Uint8ClampedArray,
+               Int16Array, Uint16Array, Int32Array, Uint32Array,
+               Float32Array, Float64Array,
+               ArrayBuffer]) {
   assertEq(C[Symbol.species], C);
 }
 
-for (C of [Map, Set]) {
+for (C of [Map, Set,
+           TypedArray,
+           ArrayBuffer]) {
   var desc = Object.getOwnPropertyDescriptor(C, Symbol.species);
   assertDeepEq(Object.keys(desc).sort(), ["configurable", "enumerable", "get", "set"]);
   assertEq(desc.set, undefined);
   assertEq(desc.enumerable, false);
   assertEq(desc.configurable, true);
   assertEq(desc.get.apply(null), null);
   assertEq(desc.get.apply(undefined), undefined);
   assertEq(desc.get.apply(42), 42);
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -129,16 +129,21 @@ const JSFunctionSpec ArrayBufferObject::
 };
 
 const JSFunctionSpec ArrayBufferObject::jsstaticfuncs[] = {
     JS_FN("isView", ArrayBufferObject::fun_isView, 1, 0),
     JS_SELF_HOSTED_FN("slice", "ArrayBufferStaticSlice", 3,0),
     JS_FS_END
 };
 
+const JSPropertySpec ArrayBufferObject::jsstaticprops[] = {
+    JS_SELF_HOSTED_SYM_GET(species, "ArrayBufferSpecies", 0),
+    JS_PS_END
+};
+
 bool
 js::IsArrayBuffer(HandleValue v)
 {
     return v.isObject() && v.toObject().is<ArrayBufferObject>();
 }
 
 bool
 js::IsArrayBuffer(HandleObject obj)
@@ -1440,14 +1445,17 @@ js::InitArrayBufferClass(JSContext* cx, 
 
     if (!NativeDefineProperty(cx, arrayBufferProto, byteLengthId, UndefinedHandleValue,
                               JS_DATA_TO_FUNC_PTR(GetterOp, getter), nullptr, attrs))
         return nullptr;
 
     if (!JS_DefineFunctions(cx, ctor, ArrayBufferObject::jsstaticfuncs))
         return nullptr;
 
+    if (!JS_DefineProperties(cx, ctor, ArrayBufferObject::jsstaticprops))
+        return nullptr;
+
     if (!JS_DefineFunctions(cx, arrayBufferProto, ArrayBufferObject::jsfuncs))
         return nullptr;
 
     return arrayBufferProto;
 }
 
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -193,26 +193,29 @@ class ArrayBufferObject : public ArrayBu
         explicit operator bool() const { return data_ != nullptr; }
     };
 
     static const Class class_;
 
     static const Class protoClass;
     static const JSFunctionSpec jsfuncs[];
     static const JSFunctionSpec jsstaticfuncs[];
+    static const JSPropertySpec jsstaticprops[];
 
     static bool byteLengthGetter(JSContext* cx, unsigned argc, Value* vp);
 
     static bool fun_slice(JSContext* cx, unsigned argc, Value* vp);
 
     static bool fun_isView(JSContext* cx, unsigned argc, Value* vp);
 #ifdef NIGHTLY_BUILD
     static bool fun_transfer(JSContext* cx, unsigned argc, Value* vp);
 #endif
 
+    static bool fun_species(JSContext* cx, unsigned argc, Value* vp);
+
     static bool class_constructor(JSContext* cx, unsigned argc, Value* vp);
 
     static ArrayBufferObject* create(JSContext* cx, uint32_t nbytes,
                                      BufferContents contents,
                                      OwnsState ownsState = OwnsData,
                                      HandleObject proto = nullptr,
                                      NewObjectKind newKind = GenericObject);
     static ArrayBufferObject* create(JSContext* cx, uint32_t nbytes,
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -856,22 +856,28 @@ TypedArrayObject::protoFunctions[] = {
 
 /* static */ const JSFunctionSpec
 TypedArrayObject::staticFunctions[] = {
     JS_SELF_HOSTED_FN("from", "TypedArrayStaticFrom", 3, 0),
     JS_SELF_HOSTED_FN("of", "TypedArrayStaticOf", 0, 0),
     JS_FS_END
 };
 
+/* static */ const JSPropertySpec
+TypedArrayObject::staticProperties[] = {
+    JS_SELF_HOSTED_SYM_GET(species, "TypedArraySpecies", 0),
+    JS_PS_END
+};
+
 static const ClassSpec
 TypedArrayObjectSharedTypedArrayPrototypeClassSpec = {
     GenericCreateConstructor<TypedArrayConstructor, 3, gc::AllocKind::FUNCTION>,
     GenericCreatePrototype,
     TypedArrayObject::staticFunctions,
-    nullptr,
+    TypedArrayObject::staticProperties,
     TypedArrayObject::protoFunctions,
     TypedArrayObject::protoAccessors,
     nullptr,
     ClassSpec::DontDefineConstructor
 };
 
 /* static */ const Class
 TypedArrayObject::sharedTypedArrayPrototypeClass = {
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -253,16 +253,17 @@ class TypedArrayObject : public NativeOb
     {
         CallArgs args = CallArgsFromVp(argc, vp);
         return CallNonGenericMethod<is, GetterImpl<ValueGetter>>(cx, args);
     }
 
     static const JSFunctionSpec protoFunctions[];
     static const JSPropertySpec protoAccessors[];
     static const JSFunctionSpec staticFunctions[];
+    static const JSPropertySpec staticProperties[];
 
     /* Accessors and functions */
 
     static bool is(HandleValue v);
 
     static bool set(JSContext* cx, unsigned argc, Value* vp);
 };