Bug 1102870: Add Float32x4 and Int32x4 to the list of Scalar::Types; r=sfink,luke
authorBenjamin Bouvier <benj@benj.me>
Fri, 05 Dec 2014 05:01:47 +0100
changeset 218441 3a7cfe0628b540f3b01b22e6faadb6b0353126b6
parent 218440 92d3bf8747e8d23bd43aca47b3b89cca6d948ecb
child 218442 9f6708bccc56cf1ddf13bacf967ddbb70e5b8ff4
push idunknown
push userunknown
push dateunknown
reviewerssfink, luke
bugs1102870
milestone37.0a1
Bug 1102870: Add Float32x4 and Int32x4 to the list of Scalar::Types; r=sfink,luke
dom/canvas/WebGL2ContextTextures.cpp
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextGL.cpp
dom/canvas/WebGLContextValidate.cpp
js/src/builtin/TypedObject.cpp
js/src/builtin/TypedObject.h
js/src/builtin/TypedObjectConstants.h
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
js/src/jsapi-tests/testArrayBufferView.cpp
js/src/jsfriendapi.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/vm/SharedTypedArrayObject.cpp
js/src/vm/SharedTypedArrayObject.h
js/src/vm/StructuredClone.cpp
js/src/vm/TypedArrayCommon.h
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
--- a/dom/canvas/WebGL2ContextTextures.cpp
+++ b/dom/canvas/WebGL2ContextTextures.cpp
@@ -212,17 +212,17 @@ WebGL2Context::TexImage3D(GLenum target,
         return;
 
     void* data;
     size_t dataLength;
     js::Scalar::Type jsArrayType;
     if (pixels.IsNull()) {
         data = nullptr;
         dataLength = 0;
-        jsArrayType = js::Scalar::TypeMax;
+        jsArrayType = js::Scalar::MaxTypedArrayViewType;
     } else {
         const ArrayBufferView& view = pixels.Value();
         view.ComputeLengthAndData();
 
         data = view.Data();
         dataLength = view.Length();
         jsArrayType = JS_GetArrayBufferViewType(view.Obj());
     }
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -592,17 +592,17 @@ public:
         if (rv.Failed() || !data)
             return;
 
         gfx::IntSize size = data->GetSize();
         uint32_t byteLength = data->Stride() * size.height;
         return TexImage2D_base(texImageTarget, level, internalFormat,
                                size.width, size.height, data->Stride(), 0,
                                format, type, data->GetData(), byteLength,
-                               js::Scalar::TypeMax, srcFormat,
+                               js::Scalar::MaxTypedArrayViewType, srcFormat,
                                mPixelStorePremultiplyAlpha);
     }
 
     void TexParameterf(GLenum target, GLenum pname, GLfloat param) {
         TexParameter_base(target, pname, nullptr, &param);
     }
     void TexParameteri(GLenum target, GLenum pname, GLint param) {
         TexParameter_base(target, pname, &param, nullptr);
@@ -667,17 +667,17 @@ public:
         if (rv.Failed() || !data)
             return;
 
         gfx::IntSize size = data->GetSize();
         uint32_t byteLength = data->Stride() * size.height;
         return TexSubImage2D_base(texImageTarget.get(), level, xoffset, yoffset,
                                   size.width, size.height, data->Stride(),
                                   format, type, data->GetData(), byteLength,
-                                  js::Scalar::TypeMax, srcFormat,
+                                  js::Scalar::MaxTypedArrayViewType, srcFormat,
                                   mPixelStorePremultiplyAlpha);
     }
 
     void Uniform1i(WebGLUniformLocation* loc, GLint x);
     void Uniform2i(WebGLUniformLocation* loc, GLint x, GLint y);
     void Uniform3i(WebGLUniformLocation* loc, GLint x, GLint y, GLint z);
     void Uniform4i(WebGLUniformLocation* loc, GLint x, GLint y, GLint z,
                    GLint w);
@@ -1250,17 +1250,17 @@ protected:
 
     void Invalidate();
     void DestroyResourcesAndContext();
 
     void MakeContextCurrent() const;
 
     // helpers
 
-    // If `isArrayType is TypeMax, it means no array.
+    // If jsArrayType is MaxTypedArrayViewType, it means no array.
     void TexImage2D_base(TexImageTarget texImageTarget, GLint level,
                          GLenum internalFormat, GLsizei width,
                          GLsizei height, GLsizei srcStrideOrZero, GLint border,
                          GLenum format, GLenum type, void* data,
                          uint32_t byteLength, js::Scalar::Type jsArrayType,
                          WebGLTexelFormat srcFormat, bool srcPremultiplied);
     void TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
                             GLint xoffset, GLint yoffset, GLsizei width,
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -3998,17 +3998,17 @@ WebGLContext::TexImage2D(GLenum rawTarge
         return;
 
     void* data;
     uint32_t length;
     js::Scalar::Type jsArrayType;
     if (pixels.IsNull()) {
         data = nullptr;
         length = 0;
-        jsArrayType = js::Scalar::TypeMax;
+        jsArrayType = js::Scalar::MaxTypedArrayViewType;
     } else {
         const ArrayBufferView& view = pixels.Value();
         view.ComputeLengthAndData();
 
         data = view.Data();
         length = view.Length();
         jsArrayType = JS_GetArrayBufferViewType(view.Obj());
     }
@@ -4042,17 +4042,17 @@ WebGLContext::TexImage2D(GLenum rawTarge
     void* pixelData = arr.Data();
     const uint32_t pixelDataLength = arr.Length();
 
     if (!ValidateTexImageTarget(rawTarget, WebGLTexImageFunc::TexImage, WebGLTexDimensions::Tex2D))
         return;
 
     return TexImage2D_base(rawTarget, level, internalformat, pixels->Width(),
                            pixels->Height(), 4*pixels->Width(), 0,
-                           format, type, pixelData, pixelDataLength, js::Scalar::TypeMax,
+                           format, type, pixelData, pixelDataLength, js::Scalar::MaxTypedArrayViewType,
                            WebGLTexelFormat::RGBA8, false);
 }
 
 
 void
 WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
                                  GLint xoffset, GLint yoffset,
                                  GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
@@ -4225,17 +4225,17 @@ WebGLContext::TexSubImage2D(GLenum targe
     DebugOnly<bool> inited = arr.Init(pixels->GetDataObject());
     MOZ_ASSERT(inited);
     arr.ComputeLengthAndData();
 
     return TexSubImage2D_base(target, level, xoffset, yoffset,
                               pixels->Width(), pixels->Height(),
                               4*pixels->Width(), format, type,
                               arr.Data(), arr.Length(),
-                              js::Scalar::TypeMax,
+                              js::Scalar::MaxTypedArrayViewType,
                               WebGLTexelFormat::RGBA8, false);
 }
 
 void
 WebGLContext::LoseContext()
 {
     if (IsContextLost())
         return ErrorInvalidOperation("loseContext: Context is already lost.");
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -1207,19 +1207,19 @@ WebGLContext::ValidateCopyTexImageIntern
  *
  * It is assumed that type has previously been validated.
  */
 bool
 WebGLContext::ValidateTexInputData(GLenum type, js::Scalar::Type jsArrayType,
                                    WebGLTexImageFunc func,
                                    WebGLTexDimensions dims)
 {
-    // We're using js::Scalar::TypeMax as dummy value for when the tex source
-    // wasn't a typed array.
-    if (jsArrayType == js::Scalar::TypeMax)
+    // We're using js::Scalar::MaxTypedArrayViewType as dummy value for when
+    // the tex source wasn't a typed array.
+    if (jsArrayType == js::Scalar::MaxTypedArrayViewType)
         return true;
 
     const char invalidTypedArray[] = "%s: Invalid typed array type for given"
                                      " texture data type.";
 
     bool validInput = false;
     switch (type) {
     case LOCAL_GL_UNSIGNED_BYTE:
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -272,17 +272,19 @@ ScalarTypeDescr::alignment(Type t)
 /*static*/ const char *
 ScalarTypeDescr::typeName(Type type)
 {
     switch (type) {
 #define NUMERIC_TYPE_TO_STRING(constant_, type_, name_) \
         case constant_: return #name_;
         JS_FOR_EACH_SCALAR_TYPE_REPR(NUMERIC_TYPE_TO_STRING)
 #undef NUMERIC_TYPE_TO_STRING
-      case Scalar::TypeMax:
+      case Scalar::Float32x4:
+      case Scalar::Int32x4:
+      case Scalar::MaxTypedArrayViewType:
         MOZ_CRASH();
     }
     MOZ_CRASH("Invalid type");
 }
 
 bool
 ScalarTypeDescr::call(JSContext *cx, unsigned argc, Value *vp)
 {
@@ -308,17 +310,19 @@ ScalarTypeDescr::call(JSContext *cx, uns
       case constant_: {                                                       \
           type_ converted = ConvertScalar<type_>(number);                     \
           args.rval().setNumber((double) converted);                          \
           return true;                                                        \
       }
 
         JS_FOR_EACH_SCALAR_TYPE_REPR(SCALARTYPE_CALL)
 #undef SCALARTYPE_CALL
-      case Scalar::TypeMax:
+      case Scalar::Float32x4:
+      case Scalar::Int32x4:
+      case Scalar::MaxTypedArrayViewType:
         MOZ_CRASH();
     }
     return true;
 }
 
 /***************************************************************************
  * Reference type objects
  *
--- a/js/src/builtin/TypedObject.h
+++ b/js/src/builtin/TypedObject.h
@@ -262,16 +262,20 @@ class ScalarTypeDescr : public SimpleTyp
         static_assert(Scalar::Uint32 == JS_SCALARTYPEREPR_UINT32,
                       "TypedObjectConstants.h must be consistent with Scalar::Type");
         static_assert(Scalar::Float32 == JS_SCALARTYPEREPR_FLOAT32,
                       "TypedObjectConstants.h must be consistent with Scalar::Type");
         static_assert(Scalar::Float64 == JS_SCALARTYPEREPR_FLOAT64,
                       "TypedObjectConstants.h must be consistent with Scalar::Type");
         static_assert(Scalar::Uint8Clamped == JS_SCALARTYPEREPR_UINT8_CLAMPED,
                       "TypedObjectConstants.h must be consistent with Scalar::Type");
+        static_assert(Scalar::Float32x4 == JS_SCALARTYPEREPR_FLOAT32X4,
+                      "TypedObjectConstants.h must be consistent with Scalar::Type");
+        static_assert(Scalar::Int32x4 == JS_SCALARTYPEREPR_INT32X4,
+                      "TypedObjectConstants.h must be consistent with Scalar::Type");
 
         return Type(getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32());
     }
 
     static bool call(JSContext *cx, unsigned argc, Value *vp);
 };
 
 // Enumerates the cases of ScalarTypeDescr::Type which have
--- a/js/src/builtin/TypedObjectConstants.h
+++ b/js/src/builtin/TypedObjectConstants.h
@@ -63,16 +63,18 @@
 #define JS_SCALARTYPEREPR_UINT8         1
 #define JS_SCALARTYPEREPR_INT16         2
 #define JS_SCALARTYPEREPR_UINT16        3
 #define JS_SCALARTYPEREPR_INT32         4
 #define JS_SCALARTYPEREPR_UINT32        5
 #define JS_SCALARTYPEREPR_FLOAT32       6
 #define JS_SCALARTYPEREPR_FLOAT64       7
 #define JS_SCALARTYPEREPR_UINT8_CLAMPED 8
+#define JS_SCALARTYPEREPR_FLOAT32X4     10
+#define JS_SCALARTYPEREPR_INT32X4       11
 
 // These constants are for use exclusively in JS code. In C++ code,
 // prefer ReferenceTypeRepresentation::TYPE_ANY etc, which allows
 // you to write a switch which will receive a warning if you omit a
 // case.
 #define JS_REFERENCETYPEREPR_ANY        0
 #define JS_REFERENCETYPEREPR_OBJECT     1
 #define JS_REFERENCETYPEREPR_STRING     2
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -255,24 +255,28 @@ IonBuilder::inlineNativeGetter(CallInfo 
     // Try to optimize typed array lengths. There is one getter on
     // %TypedArray%.prototype for typed arrays and one getter on
     // SharedTypedArray.prototype for shared typed arrays.  Make sure we're
     // accessing the right one for the type of the instance object.
     if (thisTypes) {
         Scalar::Type type;
 
         type = thisTypes->getTypedArrayType();
-        if (type != Scalar::TypeMax && TypedArrayObject::isOriginalLengthGetter(native)) {
+        if (type != Scalar::MaxTypedArrayViewType &&
+            TypedArrayObject::isOriginalLengthGetter(native))
+        {
             MInstruction *length = addTypedArrayLength(callInfo.thisArg());
             current->push(length);
             return InliningStatus_Inlined;
         }
 
         type = thisTypes->getSharedTypedArrayType();
-        if (type != Scalar::TypeMax && SharedTypedArrayObject::isOriginalLengthGetter(type, native)) {
+        if (type != Scalar::MaxTypedArrayViewType &&
+            SharedTypedArrayObject::isOriginalLengthGetter(type, native))
+        {
             MInstruction *length = addTypedArrayLength(callInfo.thisArg());
             current->push(length);
             return InliningStatus_Inlined;
         }
     }
 
     return InliningStatus_NotInlined;
 }
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -3972,20 +3972,20 @@ jit::ElementAccessIsAnyTypedArray(MDefin
     if (id->type() != MIRType_Int32 && id->type() != MIRType_Double)
         return false;
 
     types::TemporaryTypeSet *types = obj->resultTypeSet();
     if (!types)
         return false;
 
     *arrayType = types->getTypedArrayType();
-    if (*arrayType != Scalar::TypeMax)
+    if (*arrayType != Scalar::MaxTypedArrayViewType)
         return true;
     *arrayType = types->getSharedTypedArrayType();
-    return *arrayType != Scalar::TypeMax;
+    return *arrayType != Scalar::MaxTypedArrayViewType;
 }
 
 bool
 jit::ElementAccessIsPacked(types::CompilerConstraintList *constraints, MDefinition *obj)
 {
     types::TemporaryTypeSet *types = obj->resultTypeSet();
     return types && !types->hasObjectFlags(constraints, types::OBJECT_FLAG_NON_PACKED);
 }
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -8482,17 +8482,17 @@ class MLoadTypedArrayElement
     {
         setResultType(MIRType_Value);
         if (requiresBarrier_)
             setGuard();         // Not removable or movable
         else
             setMovable();
         MOZ_ASSERT(IsValidElementsType(elements, offsetAdjustment));
         MOZ_ASSERT(index->type() == MIRType_Int32);
-        MOZ_ASSERT(arrayType >= 0 && arrayType < Scalar::TypeMax);
+        MOZ_ASSERT(arrayType >= 0 && arrayType < Scalar::MaxTypedArrayViewType);
     }
 
   public:
     INSTRUCTION_HEADER(LoadTypedArrayElement)
 
     static MLoadTypedArrayElement *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index,
                                        Scalar::Type arrayType,
                                        MemoryBarrierRequirement requiresBarrier=DoesNotRequireMemoryBarrier,
@@ -8560,17 +8560,17 @@ class MLoadTypedArrayElementHole
     bool allowDouble_;
 
     MLoadTypedArrayElementHole(MDefinition *object, MDefinition *index, Scalar::Type arrayType, bool allowDouble)
       : MBinaryInstruction(object, index), arrayType_(arrayType), allowDouble_(allowDouble)
     {
         setResultType(MIRType_Value);
         setMovable();
         MOZ_ASSERT(index->type() == MIRType_Int32);
-        MOZ_ASSERT(arrayType >= 0 && arrayType < Scalar::TypeMax);
+        MOZ_ASSERT(arrayType >= 0 && arrayType < Scalar::MaxTypedArrayViewType);
     }
 
   public:
     INSTRUCTION_HEADER(LoadTypedArrayElementHole)
 
     static MLoadTypedArrayElementHole *New(TempAllocator &alloc, MDefinition *object, MDefinition *index,
                                            Scalar::Type arrayType, bool allowDouble)
     {
@@ -8684,17 +8684,17 @@ class MStoreTypedArrayElement
         racy_(false)
     {
         if (requiresBarrier_)
             setGuard();         // Not removable or movable
         else
             setMovable();
         MOZ_ASSERT(IsValidElementsType(elements, offsetAdjustment));
         MOZ_ASSERT(index->type() == MIRType_Int32);
-        MOZ_ASSERT(arrayType >= 0 && arrayType < Scalar::TypeMax);
+        MOZ_ASSERT(arrayType >= 0 && arrayType < Scalar::MaxTypedArrayViewType);
     }
 
   public:
     INSTRUCTION_HEADER(StoreTypedArrayElement)
 
     static MStoreTypedArrayElement *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index,
                                         MDefinition *value, Scalar::Type arrayType,
                                         MemoryBarrierRequirement requiresBarrier = DoesNotRequireMemoryBarrier,
@@ -8762,17 +8762,17 @@ class MStoreTypedArrayElementHole
         initOperand(0, elements);
         initOperand(1, length);
         initOperand(2, index);
         initOperand(3, value);
         setMovable();
         MOZ_ASSERT(elements->type() == MIRType_Elements);
         MOZ_ASSERT(length->type() == MIRType_Int32);
         MOZ_ASSERT(index->type() == MIRType_Int32);
-        MOZ_ASSERT(arrayType >= 0 && arrayType < Scalar::TypeMax);
+        MOZ_ASSERT(arrayType >= 0 && arrayType < Scalar::MaxTypedArrayViewType);
     }
 
   public:
     INSTRUCTION_HEADER(StoreTypedArrayElementHole)
 
     static MStoreTypedArrayElementHole *New(TempAllocator &alloc, MDefinition *elements,
                                             MDefinition *length, MDefinition *index,
                                             MDefinition *value, Scalar::Type arrayType)
--- a/js/src/jsapi-tests/testArrayBufferView.cpp
+++ b/js/src/jsapi-tests/testArrayBufferView.cpp
@@ -60,17 +60,17 @@ BEGIN_TEST(testArrayBufferView_type)
                         Create<JS_NewFloat64Array, 9>,
                         JS_GetObjectAsFloat64Array,
                         js::Scalar::Float64,
                         9, 72>(cx)));
 
     CHECK((TestViewType<uint8_t,
                         CreateDataView,
                         JS_GetObjectAsArrayBufferView,
-                        js::Scalar::TypeMax,
+                        js::Scalar::MaxTypedArrayViewType,
                         8, 8>(cx)));
 
     JS::Rooted<JS::Value> hasTypedObject(cx);
     EVAL("typeof TypedObject !== 'undefined'", &hasTypedObject);
     if (hasTypedObject.isTrue()) {
         JS::Rooted<JS::Value> tval(cx);
         EVAL("var T = new TypedObject.StructType({ x: TypedObject.uint32 });\n"
              "new T(new ArrayBuffer(4));",
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -1411,34 +1411,44 @@ struct MOZ_STACK_CLASS JS_FRIEND_API(Err
 /* Implemented in jsclone.cpp. */
 
 extern JS_FRIEND_API(uint64_t)
 js_GetSCOffset(JSStructuredCloneWriter* writer);
 
 namespace js {
 namespace Scalar {
 
-/* Scalar types which can appear in typed arrays and typed objects. */
+/* Scalar types which can appear in typed arrays and typed objects.  The enum
+ * values need to be kept in sync with the JS_SCALARTYPEREPR_ constants, as
+ * well as the TypedArrayObject::classes and TypedArrayObject::protoClasses
+ * definitions.
+ */
 enum Type {
     Int8 = 0,
     Uint8,
     Int16,
     Uint16,
     Int32,
     Uint32,
     Float32,
     Float64,
 
     /*
      * Special type that is a uint8_t, but assignments are clamped to [0, 256).
      * Treat the raw data type as a uint8_t.
      */
     Uint8Clamped,
 
-    TypeMax
+    /*
+     * SIMD types don't have their own TypedArray equivalent, for now.
+     */
+    MaxTypedArrayViewType,
+
+    Float32x4,
+    Int32x4
 };
 
 static inline size_t
 byteSize(Type atype)
 {
     switch (atype) {
       case Int8:
       case Uint8:
@@ -1448,16 +1458,19 @@ byteSize(Type atype)
       case Uint16:
         return 2;
       case Int32:
       case Uint32:
       case Float32:
         return 4;
       case Float64:
         return 8;
+      case Int32x4:
+      case Float32x4:
+        return 16;
       default:
         MOZ_CRASH("invalid scalar type");
     }
 }
 
 } /* namespace Scalar */
 } /* namespace js */
 
@@ -1810,17 +1823,17 @@ JS_GetObjectAsFloat32Array(JSObject *obj
 extern JS_FRIEND_API(JSObject *)
 JS_GetObjectAsFloat64Array(JSObject *obj, uint32_t *length, double **data);
 extern JS_FRIEND_API(JSObject *)
 JS_GetObjectAsArrayBufferView(JSObject *obj, uint32_t *length, uint8_t **data);
 extern JS_FRIEND_API(JSObject *)
 JS_GetObjectAsArrayBuffer(JSObject *obj, uint32_t *length, uint8_t **data);
 
 /*
- * Get the type of elements in a typed array, or TypeMax if a DataView.
+ * Get the type of elements in a typed array, or MaxTypedArrayViewType if a DataView.
  *
  * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow
  * be known that it would pass such a test: it is an ArrayBufferView or a
  * wrapper of an ArrayBufferView, and the unwrapping will succeed.
  */
 extern JS_FRIEND_API(js::Scalar::Type)
 JS_GetArrayBufferViewType(JSObject *obj);
 
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -2061,27 +2061,27 @@ TemporaryTypeSet::forAllClasses(bool (*f
 
 Scalar::Type
 TemporaryTypeSet::getTypedArrayType()
 {
     const Class *clasp = getKnownClass();
 
     if (clasp && IsTypedArrayClass(clasp))
         return (Scalar::Type) (clasp - &TypedArrayObject::classes[0]);
-    return Scalar::TypeMax;
+    return Scalar::MaxTypedArrayViewType;
 }
 
 Scalar::Type
 TemporaryTypeSet::getSharedTypedArrayType()
 {
     const Class *clasp = getKnownClass();
 
     if (clasp && IsSharedTypedArrayClass(clasp))
         return (Scalar::Type) (clasp - &SharedTypedArrayObject::classes[0]);
-    return Scalar::TypeMax;
+    return Scalar::MaxTypedArrayViewType;
 }
 
 bool
 TypeSet::isDOMClass()
 {
     if (unknownObject())
         return false;
 
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -793,20 +793,20 @@ class TemporaryTypeSet : public TypeSet
     /* Apply func to the members of the set and return an appropriate result.
      * The iteration may end early if the result becomes known early.
      */
     ForAllResult forAllClasses(bool (*func)(const Class *clasp));
 
     /* Get the prototype shared by all objects in this set, or nullptr. */
     JSObject *getCommonPrototype();
 
-    /* Get the typed array type of all objects in this set, or Scalar::TypeMax. */
+    /* Get the typed array type of all objects in this set, or Scalar::MaxTypedArrayViewType. */
     Scalar::Type getTypedArrayType();
 
-    /* Get the shared typed array type of all objects in this set, or Scalar::TypeMax. */
+    /* Get the shared typed array type of all objects in this set, or Scalar::MaxTypedArrayViewType. */
     Scalar::Type getSharedTypedArrayType();
 
     /* Whether clasp->isCallable() is true for one or more objects in this set. */
     bool maybeCallable();
 
     /* Whether clasp->emulatesUndefined() is true for one or more objects in this set. */
     bool maybeEmulatesUndefined();
 
--- a/js/src/vm/SharedTypedArrayObject.cpp
+++ b/js/src/vm/SharedTypedArrayObject.cpp
@@ -54,17 +54,17 @@ using mozilla::NegativeInfinity;
 using mozilla::PodCopy;
 using mozilla::PositiveInfinity;
 using JS::CanonicalizeNaN;
 using JS::GenericNaN;
 
 TypedArrayLayout SharedTypedArrayObject::layout_(true, // shared
                                                  false, // neuterable
                                                  &SharedTypedArrayObject::classes[0],
-                                                 &SharedTypedArrayObject::classes[Scalar::TypeMax]);
+                                                 &SharedTypedArrayObject::classes[Scalar::MaxTypedArrayViewType]);
 
 inline void
 InitSharedArrayBufferViewDataPointer(SharedTypedArrayObject *obj, SharedArrayBufferObject *buffer, size_t byteOffset)
 {
     /*
      * N.B. The base of the array's data is stored in the object's
      * private data rather than a slot to avoid the restriction that
      * private Values that are pointers must have the low bits clear.
@@ -768,29 +768,29 @@ IMPL_SHARED_TYPED_ARRAY_STATICS(Uint8Arr
 IMPL_SHARED_TYPED_ARRAY_STATICS(Int16Array)
 IMPL_SHARED_TYPED_ARRAY_STATICS(Uint16Array)
 IMPL_SHARED_TYPED_ARRAY_STATICS(Int32Array)
 IMPL_SHARED_TYPED_ARRAY_STATICS(Uint32Array)
 IMPL_SHARED_TYPED_ARRAY_STATICS(Float32Array)
 IMPL_SHARED_TYPED_ARRAY_STATICS(Float64Array)
 IMPL_SHARED_TYPED_ARRAY_STATICS(Uint8ClampedArray)
 
-const Class SharedTypedArrayObject::classes[Scalar::TypeMax] = {
+const Class SharedTypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = {
     IMPL_SHARED_TYPED_ARRAY_FAST_CLASS(Int8Array),
     IMPL_SHARED_TYPED_ARRAY_FAST_CLASS(Uint8Array),
     IMPL_SHARED_TYPED_ARRAY_FAST_CLASS(Int16Array),
     IMPL_SHARED_TYPED_ARRAY_FAST_CLASS(Uint16Array),
     IMPL_SHARED_TYPED_ARRAY_FAST_CLASS(Int32Array),
     IMPL_SHARED_TYPED_ARRAY_FAST_CLASS(Uint32Array),
     IMPL_SHARED_TYPED_ARRAY_FAST_CLASS(Float32Array),
     IMPL_SHARED_TYPED_ARRAY_FAST_CLASS(Float64Array),
     IMPL_SHARED_TYPED_ARRAY_FAST_CLASS(Uint8ClampedArray)
 };
 
-const Class SharedTypedArrayObject::protoClasses[Scalar::TypeMax] = {
+const Class SharedTypedArrayObject::protoClasses[Scalar::MaxTypedArrayViewType] = {
     IMPL_SHARED_TYPED_ARRAY_PROTO_CLASS(Int8Array),
     IMPL_SHARED_TYPED_ARRAY_PROTO_CLASS(Uint8Array),
     IMPL_SHARED_TYPED_ARRAY_PROTO_CLASS(Int16Array),
     IMPL_SHARED_TYPED_ARRAY_PROTO_CLASS(Uint16Array),
     IMPL_SHARED_TYPED_ARRAY_PROTO_CLASS(Int32Array),
     IMPL_SHARED_TYPED_ARRAY_PROTO_CLASS(Uint32Array),
     IMPL_SHARED_TYPED_ARRAY_PROTO_CLASS(Float32Array),
     IMPL_SHARED_TYPED_ARRAY_PROTO_CLASS(Float64Array),
--- a/js/src/vm/SharedTypedArrayObject.h
+++ b/js/src/vm/SharedTypedArrayObject.h
@@ -45,18 +45,18 @@ class SharedTypedArrayObject : public Na
 
     static bool sameBuffer(Handle<SharedTypedArrayObject*> a, Handle<SharedTypedArrayObject*> b) {
         // Object equality isn't good enough for shared typed arrays.
         return a->buffer()->globalID() == b->buffer()->globalID();
     }
 
     static bool is(HandleValue v);
 
-    static const Class classes[Scalar::TypeMax];
-    static const Class protoClasses[Scalar::TypeMax];
+    static const Class classes[Scalar::MaxTypedArrayViewType];
+    static const Class protoClasses[Scalar::MaxTypedArrayViewType];
 
     static SharedArrayBufferObject *bufferObject(JSContext *cx, Handle<SharedTypedArrayObject *> obj);
 
     static Value bufferValue(SharedTypedArrayObject *tarr) {
         return tarr->getFixedSlot(BUFFER_SLOT);
     }
     static Value byteOffsetValue(SharedTypedArrayObject *tarr) {
         return tarr->getFixedSlot(BYTEOFFSET_SLOT);
@@ -105,24 +105,24 @@ class SharedTypedArrayObject : public Na
         return layout_;
     }
 };
 
 inline bool
 IsSharedTypedArrayClass(const Class *clasp)
 {
     return &SharedTypedArrayObject::classes[0] <= clasp &&
-           clasp < &SharedTypedArrayObject::classes[Scalar::TypeMax];
+           clasp < &SharedTypedArrayObject::classes[Scalar::MaxTypedArrayViewType];
 }
 
 inline bool
 IsSharedTypedArrayProtoClass(const Class *clasp)
 {
     return &SharedTypedArrayObject::protoClasses[0] <= clasp &&
-           clasp < &SharedTypedArrayObject::protoClasses[Scalar::TypeMax];
+           clasp < &SharedTypedArrayObject::protoClasses[Scalar::MaxTypedArrayViewType];
 }
 
 bool
 IsSharedTypedArrayConstructor(HandleValue v, uint32_t type);
 
 inline Scalar::Type
 SharedTypedArrayObject::type() const
 {
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -95,17 +95,17 @@ enum StructuredDataType MOZ_ENUM_TYPE(ui
     SCTAG_TYPED_ARRAY_V1_UINT8 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint8,
     SCTAG_TYPED_ARRAY_V1_INT16 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Int16,
     SCTAG_TYPED_ARRAY_V1_UINT16 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint16,
     SCTAG_TYPED_ARRAY_V1_INT32 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Int32,
     SCTAG_TYPED_ARRAY_V1_UINT32 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint32,
     SCTAG_TYPED_ARRAY_V1_FLOAT32 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Float32,
     SCTAG_TYPED_ARRAY_V1_FLOAT64 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Float64,
     SCTAG_TYPED_ARRAY_V1_UINT8_CLAMPED = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint8Clamped,
-    SCTAG_TYPED_ARRAY_V1_MAX = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::TypeMax - 1,
+    SCTAG_TYPED_ARRAY_V1_MAX = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::MaxTypedArrayViewType - 1,
 
     /*
      * Define a separate range of numbers for Transferable-only tags, since
      * they are not used for persistent clone buffers and therefore do not
      * require bumping JS_STRUCTURED_CLONE_VERSION.
      */
     SCTAG_TRANSFER_MAP_HEADER = 0xFFFF0200,
     SCTAG_TRANSFER_MAP_PENDING_ENTRY,
--- a/js/src/vm/TypedArrayCommon.h
+++ b/js/src/vm/TypedArrayCommon.h
@@ -730,17 +730,19 @@ class TypedArrayMethods
           case Scalar::Uint32:
             return ElementSpecific<Uint32ArrayType>::setFromTypedArray(cx, target, source, offset);
           case Scalar::Float32:
             return ElementSpecific<Float32ArrayType>::setFromTypedArray(cx, target, source, offset);
           case Scalar::Float64:
             return ElementSpecific<Float64ArrayType>::setFromTypedArray(cx, target, source, offset);
           case Scalar::Uint8Clamped:
             return ElementSpecific<Uint8ClampedArrayType>::setFromTypedArray(cx, target, source, offset);
-          case Scalar::TypeMax:
+          case Scalar::Float32x4:
+          case Scalar::Int32x4:
+          case Scalar::MaxTypedArrayViewType:
             break;
         }
 
         MOZ_CRASH("nonsense target element type");
     }
 
     static bool
     setFromNonTypedArray(JSContext *cx, Handle<AnyTypedArray*> target, HandleObject source,
@@ -762,17 +764,19 @@ class TypedArrayMethods
           case Scalar::Uint32:
             return ElementSpecific<Uint32ArrayType>::setFromNonTypedArray(cx, target, source, len, offset);
           case Scalar::Float32:
             return ElementSpecific<Float32ArrayType>::setFromNonTypedArray(cx, target, source, len, offset);
           case Scalar::Float64:
             return ElementSpecific<Float64ArrayType>::setFromNonTypedArray(cx, target, source, len, offset);
           case Scalar::Uint8Clamped:
             return ElementSpecific<Uint8ClampedArrayType>::setFromNonTypedArray(cx, target, source, len, offset);
-          case Scalar::TypeMax:
+          case Scalar::Float32x4:
+          case Scalar::Int32x4:
+          case Scalar::MaxTypedArrayViewType:
             break;
         }
 
         MOZ_CRASH("bad target array type");
     }
 };
 
 } // namespace js
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -62,17 +62,17 @@ using JS::GenericNaN;
  * The non-templated base class for the specific typed implementations.
  * This class holds all the member variables that are used by
  * the subclasses.
  */
 
 TypedArrayLayout TypedArrayObject::layout_(false, // shared
                                            true,  // neuterable
                                            &TypedArrayObject::classes[0],
-                                           &TypedArrayObject::classes[Scalar::TypeMax]);
+                                           &TypedArrayObject::classes[Scalar::MaxTypedArrayViewType]);
 
 TypedArrayLayout::TypedArrayLayout(bool isShared, bool isNeuterable, const Class *firstClass,
                                    const Class *maxClass)
     : isShared_(isShared)
     , isNeuterable_(isNeuterable)
     , firstClass_(firstClass)
     , maxClass_(maxClass)
 {
@@ -1610,17 +1610,19 @@ TypedArrayObject::getElement(uint32_t in
       case Scalar::Uint32:
         return Uint32Array::getIndexValue(this, index);
       case Scalar::Float32:
         return Float32Array::getIndexValue(this, index);
       case Scalar::Float64:
         return Float64Array::getIndexValue(this, index);
       case Scalar::Uint8Clamped:
         return Uint8ClampedArray::getIndexValue(this, index);
-      case Scalar::TypeMax:
+      case Scalar::Float32x4:
+      case Scalar::Int32x4:
+      case Scalar::MaxTypedArrayViewType:
         break;
     }
 
     MOZ_CRASH("Unknown TypedArray type");
 }
 
 void
 TypedArrayObject::setElement(TypedArrayObject &obj, uint32_t index, double d)
@@ -1650,17 +1652,19 @@ TypedArrayObject::setElement(TypedArrayO
         Uint32Array::setIndexValue(obj, index, d);
         return;
       case Scalar::Float32:
         Float32Array::setIndexValue(obj, index, d);
         return;
       case Scalar::Float64:
         Float64Array::setIndexValue(obj, index, d);
         return;
-      case Scalar::TypeMax:
+      case Scalar::Float32x4:
+      case Scalar::Int32x4:
+      case Scalar::MaxTypedArrayViewType:
         break;
     }
 
     MOZ_CRASH("Unknown TypedArray type");
 }
 
 /***
  *** JS impl
@@ -1771,17 +1775,17 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Flo
     nullptr,                 /* finalize    */                                 \
     nullptr,                 /* call        */                                 \
     nullptr,                 /* hasInstance */                                 \
     nullptr,                 /* construct   */                                 \
     TypedArrayObject::trace, /* trace  */                                      \
     TYPED_ARRAY_CLASS_SPEC(_typedArray)                                        \
 }
 
-const Class TypedArrayObject::classes[Scalar::TypeMax] = {
+const Class TypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = {
     IMPL_TYPED_ARRAY_CLASS(Int8Array),
     IMPL_TYPED_ARRAY_CLASS(Uint8Array),
     IMPL_TYPED_ARRAY_CLASS(Int16Array),
     IMPL_TYPED_ARRAY_CLASS(Uint16Array),
     IMPL_TYPED_ARRAY_CLASS(Int32Array),
     IMPL_TYPED_ARRAY_CLASS(Uint32Array),
     IMPL_TYPED_ARRAY_CLASS(Float32Array),
     IMPL_TYPED_ARRAY_CLASS(Float64Array),
@@ -1824,17 +1828,17 @@ const Class TypedArrayObject::classes[Sc
         nullptr, \
         nullptr, \
         nullptr, \
         nullptr, \
         JSProto_TypedArray \
     } \
 }
 
-const Class TypedArrayObject::protoClasses[Scalar::TypeMax] = {
+const Class TypedArrayObject::protoClasses[Scalar::MaxTypedArrayViewType] = {
     IMPL_TYPED_ARRAY_PROTO_CLASS(Int8Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Int16Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Uint16Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Int32Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Uint32Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Float32Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Float64Array),
@@ -2016,17 +2020,17 @@ js::IsTypedArrayConstructor(HandleValue 
       case Scalar::Uint32:
         return IsNativeFunction(v, Uint32Array::class_constructor);
       case Scalar::Float32:
         return IsNativeFunction(v, Float32Array::class_constructor);
       case Scalar::Float64:
         return IsNativeFunction(v, Float64Array::class_constructor);
       case Scalar::Uint8Clamped:
         return IsNativeFunction(v, Uint8ClampedArray::class_constructor);
-      case Scalar::TypeMax:
+      case Scalar::MaxTypedArrayViewType:
         break;
     }
     MOZ_CRASH("unexpected typed array type");
 }
 
 template <typename CharT>
 bool
 js::StringIsTypedArrayIndex(const CharT *s, size_t length, uint64_t *indexp)
@@ -2117,22 +2121,22 @@ JS_GetTypedArrayByteLength(JSObject *obj
     return obj->as<TypedArrayObject>().byteLength();
 }
 
 JS_FRIEND_API(js::Scalar::Type)
 JS_GetArrayBufferViewType(JSObject *obj)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
-        return Scalar::TypeMax;
+        return Scalar::MaxTypedArrayViewType;
 
     if (obj->is<TypedArrayObject>())
         return obj->as<TypedArrayObject>().type();
     else if (obj->is<DataViewObject>())
-        return Scalar::TypeMax;
+        return Scalar::MaxTypedArrayViewType;
     MOZ_CRASH("invalid ArrayBufferView type");
 }
 
 JS_FRIEND_API(int8_t *)
 JS_GetInt8ArrayData(JSObject *obj, const JS::AutoCheckCannotGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -82,27 +82,27 @@ class TypedArrayObject : public NativeOb
     typedef ArrayBufferObject BufferType;
 
     template<typename T> struct OfType;
 
     static bool sameBuffer(Handle<TypedArrayObject*> a, Handle<TypedArrayObject*> b) {
         return a->buffer() == b->buffer();
     }
 
-    static const Class classes[Scalar::TypeMax];
-    static const Class protoClasses[Scalar::TypeMax];
+    static const Class classes[Scalar::MaxTypedArrayViewType];
+    static const Class protoClasses[Scalar::MaxTypedArrayViewType];
     static const Class sharedTypedArrayPrototypeClass;
 
     static const Class *classForType(Scalar::Type type) {
-        MOZ_ASSERT(type < Scalar::TypeMax);
+        MOZ_ASSERT(type < Scalar::MaxTypedArrayViewType);
         return &classes[type];
     }
 
     static const Class *protoClassForType(Scalar::Type type) {
-        MOZ_ASSERT(type < Scalar::TypeMax);
+        MOZ_ASSERT(type < Scalar::MaxTypedArrayViewType);
         return &protoClasses[type];
     }
 
     static const size_t FIXED_DATA_START = TypedArrayLayout::DATA_SLOT + 1;
 
     // For typed arrays which can store their data inline, the array buffer
     // object is created lazily.
     static const uint32_t INLINE_BUFFER_LIMIT =
@@ -218,17 +218,17 @@ class TypedArrayObject : public NativeOb
     static bool set(JSContext *cx, unsigned argc, Value *vp);
     static bool subarray(JSContext *cx, unsigned argc, Value *vp);
 };
 
 inline bool
 IsTypedArrayClass(const Class *clasp)
 {
     return &TypedArrayObject::classes[0] <= clasp &&
-           clasp < &TypedArrayObject::classes[Scalar::TypeMax];
+           clasp < &TypedArrayObject::classes[Scalar::MaxTypedArrayViewType];
 }
 
 bool
 IsTypedArrayConstructor(HandleValue v, uint32_t type);
 
 inline Scalar::Type
 TypedArrayObject::type() const
 {