Bug 671630 - Convert typed-array initialization code from being 'templatized' by a macro to being templatized by, well, a template. r=mrbkap
authorJeff Walden <jwalden@mit.edu>
Wed, 04 May 2011 16:54:23 -0400
changeset 73863 64ca7770ab496d0c354c7704532fa54c335e5282
parent 73862 fbf02dd1803ea40e3529cf970282f838c63ce439
child 73864 1e291b76d689b7d363243e4281e4f6011d3e6e43
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersmrbkap
bugs671630
milestone8.0a1
Bug 671630 - Convert typed-array initialization code from being 'templatized' by a macro to being templatized by, well, a template. r=mrbkap
js/src/jstypedarray.cpp
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -671,39 +671,27 @@ template<> inline const bool TypeIsUnsig
 template<> inline const bool TypeIsUnsigned<uint32>() { return true; }
 
 template<typename NativeType> static inline const bool TypeIsFloatingPoint() { return false; }
 template<> inline const bool TypeIsFloatingPoint<float>() { return true; }
 template<> inline const bool TypeIsFloatingPoint<double>() { return true; }
 
 template<typename NativeType> class TypedArrayTemplate;
 
-typedef TypedArrayTemplate<int8> Int8Array;
-typedef TypedArrayTemplate<uint8> Uint8Array;
-typedef TypedArrayTemplate<int16> Int16Array;
-typedef TypedArrayTemplate<uint16> Uint16Array;
-typedef TypedArrayTemplate<int32> Int32Array;
-typedef TypedArrayTemplate<uint32> Uint32Array;
-typedef TypedArrayTemplate<float> Float32Array;
-typedef TypedArrayTemplate<double> Float64Array;
-typedef TypedArrayTemplate<uint8_clamped> Uint8ClampedArray;
-
 template<typename NativeType>
 class TypedArrayTemplate
   : public TypedArray
 {
   public:
     typedef NativeType ThisType;
     typedef TypedArrayTemplate<NativeType> ThisTypeArray;
     static const int ArrayTypeID() { return TypeIDOfType<NativeType>(); }
     static const bool ArrayTypeIsUnsigned() { return TypeIsUnsigned<NativeType>(); }
     static const bool ArrayTypeIsFloatingPoint() { return TypeIsFloatingPoint<NativeType>(); }
 
-    static JSFunctionSpec jsfuncs[];
-
     static inline Class *slowClass()
     {
         return &TypedArray::slowClasses[ArrayTypeID()];
     }
 
     static inline Class *fastClass()
     {
         return &TypedArray::fastClasses[ArrayTypeID()];
@@ -1518,16 +1506,62 @@ class TypedArrayTemplate
             return NULL;
         }
 
         int32 bytelen = size * count;
         return ArrayBuffer::create(cx, bytelen);
     }
 };
 
+class Int8Array : public TypedArrayTemplate<int8> {
+  public:
+    enum { ACTUAL_TYPE = TYPE_INT8 };
+    static JSFunctionSpec jsfuncs[];
+};
+class Uint8Array : public TypedArrayTemplate<uint8> {
+  public:
+    enum { ACTUAL_TYPE = TYPE_UINT8 };
+    static JSFunctionSpec jsfuncs[];
+};
+class Int16Array : public TypedArrayTemplate<int16> {
+  public:
+    enum { ACTUAL_TYPE = TYPE_INT16 };
+    static JSFunctionSpec jsfuncs[];
+};
+class Uint16Array : public TypedArrayTemplate<uint16> {
+  public:
+    enum { ACTUAL_TYPE = TYPE_UINT16 };
+    static JSFunctionSpec jsfuncs[];
+};
+class Int32Array : public TypedArrayTemplate<int32> {
+  public:
+    enum { ACTUAL_TYPE = TYPE_INT32 };
+    static JSFunctionSpec jsfuncs[];
+};
+class Uint32Array : public TypedArrayTemplate<uint32> {
+  public:
+    enum { ACTUAL_TYPE = TYPE_UINT32 };
+    static JSFunctionSpec jsfuncs[];
+};
+class Float32Array : public TypedArrayTemplate<float> {
+  public:
+    enum { ACTUAL_TYPE = TYPE_FLOAT32 };
+    static JSFunctionSpec jsfuncs[];
+};
+class Float64Array : public TypedArrayTemplate<double> {
+  public:
+    enum { ACTUAL_TYPE = TYPE_FLOAT64 };
+    static JSFunctionSpec jsfuncs[];
+};
+class Uint8ClampedArray : public TypedArrayTemplate<uint8_clamped> {
+  public:
+    enum { ACTUAL_TYPE = TYPE_UINT8_CLAMPED };
+    static JSFunctionSpec jsfuncs[];
+};
+
 // this default implementation is only valid for integer types
 // less than 32-bits in size.
 template<typename NativeType>
 void
 TypedArrayTemplate<NativeType>::copyIndexToValue(JSContext *cx, JSObject *tarray, uint32 index, Value *vp)
 {
     JS_STATIC_ASSERT(sizeof(NativeType) < 4);
 
@@ -1737,40 +1771,43 @@ template<> JSFunctionSpec _typedArray::j
         _typedArray::obj_deleteProperty,                                       \
         _typedArray::obj_enumerate,                                            \
         _typedArray::obj_typeOf,                                               \
         NULL,       /* thisObject      */                                      \
         NULL,       /* clear           */                                      \
     }                                                                          \
 }
 
-#define INIT_TYPED_ARRAY_CLASS(_typedArray,_type)                              \
-do {                                                                           \
-    proto = js_InitClass(cx, obj, NULL,                                        \
-                         &TypedArray::slowClasses[TypedArray::_type],          \
-                         _typedArray::class_constructor, 3,                    \
-                         _typedArray::jsprops,                                 \
-                         _typedArray::jsfuncs,                                 \
-                         NULL, NULL);                                          \
-    if (!proto)                                                                \
-        return NULL;                                                           \
-    JSObject *ctor = JS_GetConstructor(cx, proto);                             \
-    if (!ctor ||                                                               \
-        !JS_DefineProperty(cx, ctor, "BYTES_PER_ELEMENT",                      \
-                           INT_TO_JSVAL(sizeof(_typedArray::ThisType)),        \
-                           JS_PropertyStub, JS_StrictPropertyStub,             \
-                           JSPROP_PERMANENT | JSPROP_READONLY) ||              \
-        !JS_DefineProperty(cx, proto, "BYTES_PER_ELEMENT",                     \
-                           INT_TO_JSVAL(sizeof(_typedArray::ThisType)),        \
-                           JS_PropertyStub, JS_StrictPropertyStub,             \
-                           JSPROP_PERMANENT | JSPROP_READONLY))                \
-    {                                                                          \
-        return NULL;                                                           \
-    }                                                                          \
-} while (0)
+template<class ArrayType>
+static inline JSObject *
+InitTypedArrayClass(JSContext *cx, GlobalObject *global)
+{
+    JSObject *proto = js_InitClass(cx, global, NULL,
+                                   &ArrayType::slowClasses[ArrayType::ACTUAL_TYPE],
+                                   ArrayType::class_constructor, 3,
+                                   ArrayType::jsprops,
+                                   ArrayType::jsfuncs,
+                                   NULL, NULL);
+    if (!proto)
+        return NULL;
+    JSObject *ctor = JS_GetConstructor(cx, proto);
+    if (!ctor ||
+        !JS_DefineProperty(cx, ctor, "BYTES_PER_ELEMENT",
+                           INT_TO_JSVAL(sizeof(typename ArrayType::ThisType)),
+                           JS_PropertyStub, JS_StrictPropertyStub,
+                           JSPROP_PERMANENT | JSPROP_READONLY) ||
+        !JS_DefineProperty(cx, proto, "BYTES_PER_ELEMENT",
+                           INT_TO_JSVAL(sizeof(typename ArrayType::ThisType)),
+                           JS_PropertyStub, JS_StrictPropertyStub,
+                           JSPROP_PERMANENT | JSPROP_READONLY))
+    {
+        return NULL;
+    }
+    return proto;
+}
 
 IMPL_TYPED_ARRAY_STATICS(Int8Array);
 IMPL_TYPED_ARRAY_STATICS(Uint8Array);
 IMPL_TYPED_ARRAY_STATICS(Int16Array);
 IMPL_TYPED_ARRAY_STATICS(Uint16Array);
 IMPL_TYPED_ARRAY_STATICS(Int32Array);
 IMPL_TYPED_ARRAY_STATICS(Uint32Array);
 IMPL_TYPED_ARRAY_STATICS(Float32Array);
@@ -1799,38 +1836,43 @@ Class TypedArray::slowClasses[TYPE_MAX] 
     IMPL_TYPED_ARRAY_SLOW_CLASS(Float32Array),
     IMPL_TYPED_ARRAY_SLOW_CLASS(Float64Array),
     IMPL_TYPED_ARRAY_SLOW_CLASS(Uint8ClampedArray)
 };
 
 JS_FRIEND_API(JSObject *)
 js_InitTypedArrayClasses(JSContext *cx, JSObject *obj)
 {
+    JS_ASSERT(obj->isNative());
+
+    GlobalObject *global = obj->asGlobal();
+
     /* Idempotency required: we initialize several things, possibly lazily. */
     JSObject *stop;
-    if (!js_GetClassObject(cx, obj, JSProto_ArrayBuffer, &stop))
+    if (!js_GetClassObject(cx, global, JSProto_ArrayBuffer, &stop))
         return NULL;
     if (stop)
         return stop;
 
-    JSObject *proto;
+    if (!InitTypedArrayClass<Int8Array>(cx, global) ||
+        !InitTypedArrayClass<Uint8Array>(cx, global) ||
+        !InitTypedArrayClass<Int16Array>(cx, global) ||
+        !InitTypedArrayClass<Uint16Array>(cx, global) ||
+        !InitTypedArrayClass<Int32Array>(cx, global) ||
+        !InitTypedArrayClass<Uint32Array>(cx, global) ||
+        !InitTypedArrayClass<Float32Array>(cx, global) ||
+        !InitTypedArrayClass<Float64Array>(cx, global) ||
+        !InitTypedArrayClass<Uint8ClampedArray>(cx, global))
+    {
+        return NULL;
+    }
 
-    INIT_TYPED_ARRAY_CLASS(Int8Array,TYPE_INT8);
-    INIT_TYPED_ARRAY_CLASS(Uint8Array,TYPE_UINT8);
-    INIT_TYPED_ARRAY_CLASS(Int16Array,TYPE_INT16);
-    INIT_TYPED_ARRAY_CLASS(Uint16Array,TYPE_UINT16);
-    INIT_TYPED_ARRAY_CLASS(Int32Array,TYPE_INT32);
-    INIT_TYPED_ARRAY_CLASS(Uint32Array,TYPE_UINT32);
-    INIT_TYPED_ARRAY_CLASS(Float32Array,TYPE_FLOAT32);
-    INIT_TYPED_ARRAY_CLASS(Float64Array,TYPE_FLOAT64);
-    INIT_TYPED_ARRAY_CLASS(Uint8ClampedArray,TYPE_UINT8_CLAMPED);
-
-    proto = js_InitClass(cx, obj, NULL, &ArrayBuffer::slowClass,
-                         ArrayBuffer::class_constructor, 1,
-                         ArrayBuffer::jsprops, NULL, NULL, NULL);
+    JSObject *proto = js_InitClass(cx, global, NULL, &ArrayBuffer::slowClass,
+                                   ArrayBuffer::class_constructor, 1,
+                                   ArrayBuffer::jsprops, NULL, NULL, NULL);
     if (!proto)
         return NULL;
 
     proto->setPrivate(NULL);
 
     /*
      * Initialize the slots to hold the length as 0
      * This is required otherwise the length of a