Bug 996076: Preparatory clean-ups, factor out error code; r=nmatsakis
authorBenjamin Bouvier <benj@benj.me>
Fri, 02 May 2014 13:11:04 +0200
changeset 181725 125d4d1381f5169f5eeeb6f83e9ded76c4bc6e92
parent 181724 5fcd868dccc636339a74e4c30587a597c6e98aa4
child 181726 e522c302dd96c6b2f494de8ea7489d232fdd2711
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersnmatsakis
bugs996076
milestone32.0a1
Bug 996076: Preparatory clean-ups, factor out error code; r=nmatsakis
js/src/builtin/SIMD.cpp
js/src/builtin/SIMD.h
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -37,17 +37,17 @@ extern const JSFunctionSpec Int32x4Metho
 
 static const char *laneNames[] = {"lane 0", "lane 1", "lane 2", "lane3"};
 
 template<typename Type32x4, int lane>
 static bool GetX4Lane(JSContext *cx, unsigned argc, Value *vp) {
     typedef typename Type32x4::Elem Elem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if(!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {
+    if (!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
                              X4TypeDescr::class_.name, laneNames[lane],
                              InformalValueTypeName(args.thisv()));
         return false;
     }
 
     TypedObject &typedObj = args.thisv().toObject().as<TypedObject>();
     TypeDescr &descr = typedObj.typeDescr();
@@ -79,17 +79,17 @@ static bool type##Lane##lane(JSContext *
 #undef FOUR_LANES_ACCESSOR
 #undef LANE_ACCESSOR
 
 template<typename Type32x4>
 static bool SignMask(JSContext *cx, unsigned argc, Value *vp) {
     typedef typename Type32x4::Elem Elem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if(!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {
+    if (!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
                              X4TypeDescr::class_.name, "signMask",
                              InformalValueTypeName(args.thisv()));
         return false;
     }
 
     TypedObject &typedObj = args.thisv().toObject().as<TypedObject>();
     TypeDescr &descr = typedObj.typeDescr();
@@ -250,43 +250,42 @@ CreateX4Class(JSContext *cx,
 
     return x4;
 }
 
 bool
 X4TypeDescr::call(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    const uint32_t LANES = 4;
+    const unsigned LANES = 4;
 
     if (args.length() < LANES) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                              args.callee().getClass()->name, "3", "s");
         return false;
     }
 
     double values[LANES];
-    for (uint32_t i = 0; i < LANES; i++) {
+    for (unsigned i = 0; i < LANES; i++) {
         if (!ToNumber(cx, args[i], &values[i]))
             return false;
     }
 
     Rooted<X4TypeDescr*> descr(cx, &args.callee().as<X4TypeDescr>());
     Rooted<TypedObject*> result(cx, TypedObject::createZeroed(cx, descr, 0));
     if (!result)
         return false;
 
     switch (descr->type()) {
 #define STORE_LANES(_constant, _type, _name)                                  \
       case _constant:                                                         \
       {                                                                       \
         _type *mem = reinterpret_cast<_type*>(result->typedMem());            \
-        for (uint32_t i = 0; i < LANES; i++) {                                \
+        for (unsigned i = 0; i < LANES; i++)                                  \
             mem[i] = ConvertScalar<_type>(values[i]);                         \
-        }                                                                     \
         break;                                                                \
       }
       JS_FOR_EACH_X4_TYPE_REPR(STORE_LANES)
 #undef STORE_LANES
     }
     args.rval().setObject(*result);
     return true;
 }
@@ -319,71 +318,66 @@ SIMDObject::initClass(JSContext *cx, Han
     // to be able to call GetTypedObjectModule(). It is NOT necessary
     // to install the TypedObjectModule global, but at the moment
     // those two things are not separable.
     if (!global->getOrCreateTypedObjectModule(cx))
         return nullptr;
 
     // Create SIMD Object.
     RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
-    if(!objProto)
+    if (!objProto)
         return nullptr;
     RootedObject SIMD(cx, NewObjectWithGivenProto(cx, &SIMDObject::class_, objProto,
                                                   global, SingletonObject));
     if (!SIMD)
         return nullptr;
 
     // float32x4
-
     RootedObject float32x4Object(cx);
     float32x4Object = CreateX4Class<Float32x4Defn>(cx, global,
                                                    cx->names().float32x4);
     if (!float32x4Object)
         return nullptr;
 
+    // Define float32x4 functions and install as a property of the SIMD object.
     RootedValue float32x4Value(cx, ObjectValue(*float32x4Object));
     if (!JS_DefineFunctions(cx, float32x4Object, Float32x4Methods) ||
         !JSObject::defineProperty(cx, SIMD, cx->names().float32x4,
                                   float32x4Value, nullptr, nullptr,
                                   JSPROP_READONLY | JSPROP_PERMANENT))
     {
         return nullptr;
     }
 
     // int32x4
-
     RootedObject int32x4Object(cx);
     int32x4Object = CreateX4Class<Int32x4Defn>(cx, global,
                                                cx->names().int32x4);
     if (!int32x4Object)
         return nullptr;
 
+    // Define int32x4 functions and install as a property of the SIMD object.
     RootedValue int32x4Value(cx, ObjectValue(*int32x4Object));
     if (!JS_DefineFunctions(cx, int32x4Object, Int32x4Methods) ||
         !JSObject::defineProperty(cx, SIMD, cx->names().int32x4,
                                   int32x4Value, nullptr, nullptr,
                                   JSPROP_READONLY | JSPROP_PERMANENT))
     {
         return nullptr;
     }
 
     RootedValue SIMDValue(cx, ObjectValue(*SIMD));
 
     // Everything is set up, install SIMD on the global object.
     if (!JSObject::defineProperty(cx, global, cx->names().SIMD, SIMDValue, nullptr, nullptr, 0))
         return nullptr;
 
     global->setConstructor(JSProto_SIMD, SIMDValue);
-
-    // Define float32x4 functions and install as a property of the SIMD object.
     global->setFloat32x4TypeDescr(*float32x4Object);
-
-    // Define int32x4 functions and install as a property of the SIMD object.
     global->setInt32x4TypeDescr(*int32x4Object);
-
     return SIMD;
 }
 
 JSObject *
 js_InitSIMDClass(JSContext *cx, HandleObject obj)
 {
     JS_ASSERT(obj->is<GlobalObject>());
     Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
@@ -557,50 +551,50 @@ struct WithFlagW {
     static inline T apply(T l, T f, T x) { return V::toType(l == 3 ? (f ? 0xFFFFFFFF : 0x0) : x); }
 };
 template<typename T, typename V>
 struct Shuffle {
     static inline int32_t apply(int32_t l, int32_t mask) { return V::toType((mask >> l) & 0x3); }
 };
 }
 
+static inline bool
+ErrorBadArgs(JSContext *cx)
+{
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
+    return false;
+}
+
 template<typename V, typename Op, typename Vret>
 static bool
 Func(JSContext *cx, unsigned argc, Value *vp)
 {
     typedef typename V::Elem Elem;
     typedef typename Vret::Elem RetElem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 1 && args.length() != 2) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
-    }
+    if (args.length() != 1 && args.length() != 2)
+        return ErrorBadArgs(cx);
 
     RetElem result[Vret::lanes];
     if (args.length() == 1) {
-        if (!IsVectorObject<V>(args[0])) {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-            return false;
-        }
+        if (!IsVectorObject<V>(args[0]))
+            return ErrorBadArgs(cx);
 
         Elem *val = TypedObjectMemory<Elem *>(args[0]);
-        for (int32_t i = 0; i < Vret::lanes; i++)
+        for (unsigned i = 0; i < Vret::lanes; i++)
             result[i] = Op::apply(val[i], 0);
     } else {
         JS_ASSERT(args.length() == 2);
-        if(!IsVectorObject<V>(args[0]) || !IsVectorObject<V>(args[1]))
-        {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-            return false;
-        }
+        if (!IsVectorObject<V>(args[0]) || !IsVectorObject<V>(args[1]))
+            return ErrorBadArgs(cx);
 
         Elem *left = TypedObjectMemory<Elem *>(args[0]);
         Elem *right = TypedObjectMemory<Elem *>(args[1]);
-        for (int32_t i = 0; i < Vret::lanes; i++)
+        for (unsigned i = 0; i < Vret::lanes; i++)
             result[i] = Op::apply(left[i], right[i]);
     }
 
     RootedObject obj(cx, Create<Vret>(cx, result));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
@@ -613,32 +607,32 @@ FuncWith(JSContext *cx, unsigned argc, V
 {
     typedef typename V::Elem Elem;
     typedef typename Vret::Elem RetElem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 2 || !IsVectorObject<V>(args[0]) ||
         (!args[1].isNumber() && !args[1].isBoolean()))
     {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
+        return ErrorBadArgs(cx);
     }
 
     Elem *val = TypedObjectMemory<Elem *>(args[0]);
     RetElem result[Vret::lanes];
 
     if (args[1].isNumber()) {
         Elem withAsNumber;
         if (!Vret::toType(cx, args[1], &withAsNumber))
             return false;
-        for (int32_t i = 0; i < Vret::lanes; i++)
+        for (unsigned i = 0; i < Vret::lanes; i++)
             result[i] = OpWith::apply(i, withAsNumber, val[i]);
-    } else if (args[1].isBoolean()) {
+    } else {
+        JS_ASSERT(args[1].isBoolean());
         bool withAsBool = args[1].toBoolean();
-        for (int32_t i = 0; i < Vret::lanes; i++)
+        for (unsigned i = 0; i < Vret::lanes; i++)
             result[i] = OpWith::apply(i, withAsBool, val[i]);
     }
 
     RootedObject obj(cx, Create<Vret>(cx, result));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
@@ -648,56 +642,47 @@ FuncWith(JSContext *cx, unsigned argc, V
 template<typename V, typename OpShuffle, typename Vret>
 static bool
 FuncShuffle(JSContext *cx, unsigned argc, Value *vp)
 {
     typedef typename V::Elem Elem;
     typedef typename Vret::Elem RetElem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 2 && args.length() != 3) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
-    }
+    if (args.length() != 2 && args.length() != 3)
+        return ErrorBadArgs(cx);
 
     RetElem result[Vret::lanes];
     if (args.length() == 2) {
         if (!IsVectorObject<V>(args[0]) || !args[1].isNumber())
-        {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-            return false;
-        }
+            return ErrorBadArgs(cx);
 
         Elem *val = TypedObjectMemory<Elem *>(args[0]);;
         Elem arg1;
         if (!Vret::toType(cx, args[1], &arg1))
             return false;
 
-        for (int32_t i = 0; i < Vret::lanes; i++)
+        for (unsigned i = 0; i < Vret::lanes; i++)
             result[i] = val[OpShuffle::apply(i * 2, arg1)];
     } else {
         JS_ASSERT(args.length() == 3);
         if (!IsVectorObject<V>(args[0]) || !IsVectorObject<V>(args[1]) || !args[2].isNumber())
-        {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-            return false;
-        }
+            return ErrorBadArgs(cx);
 
         Elem *val1 = TypedObjectMemory<Elem *>(args[0]);
         Elem *val2 = TypedObjectMemory<Elem *>(args[1]);
         Elem arg2;
         if (!Vret::toType(cx, args[2], &arg2))
             return false;
 
-        for (int32_t i = 0; i < Vret::lanes; i++) {
-            if (i < Vret::lanes / 2)
-                result[i] = val1[OpShuffle::apply(i * 2, arg2)];
-            else
-                result[i] = val2[OpShuffle::apply(i * 2, arg2)];
-        }
+        unsigned i = 0;
+        for (; i < Vret::lanes / 2; i++)
+            result[i] = val1[OpShuffle::apply(i * 2, arg2)];
+        for (; i < Vret::lanes; i++)
+            result[i] = val2[OpShuffle::apply(i * 2, arg2)];
     }
 
     RootedObject obj(cx, Create<Vret>(cx, result));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
     return true;
@@ -707,24 +692,21 @@ template<typename V, typename Vret>
 static bool
 FuncConvert(JSContext *cx, unsigned argc, Value *vp)
 {
     typedef typename V::Elem Elem;
     typedef typename Vret::Elem RetElem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 1 || !IsVectorObject<V>(args[0]))
-    {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
-    }
+        return ErrorBadArgs(cx);
 
     Elem *val = TypedObjectMemory<Elem *>(args[0]);
     RetElem result[Vret::lanes];
-    for (int32_t i = 0; i < Vret::lanes; i++)
+    for (unsigned i = 0; i < Vret::lanes; i++)
         result[i] = RetElem(val[i]);
 
     RootedObject obj(cx, Create<Vret>(cx, result));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
     return true;
@@ -733,20 +715,17 @@ FuncConvert(JSContext *cx, unsigned argc
 template<typename V, typename Vret>
 static bool
 FuncConvertBits(JSContext *cx, unsigned argc, Value *vp)
 {
     typedef typename Vret::Elem RetElem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 1 || !IsVectorObject<V>(args[0]))
-    {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
-    }
+        return ErrorBadArgs(cx);
 
     RetElem *val = TypedObjectMemory<RetElem *>(args[0]);
     RootedObject obj(cx, Create<Vret>(cx, val));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
     return true;
@@ -754,23 +733,21 @@ FuncConvertBits(JSContext *cx, unsigned 
 
 template<typename Vret>
 static bool
 FuncZero(JSContext *cx, unsigned argc, Value *vp)
 {
     typedef typename Vret::Elem RetElem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 0) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
-    }
+    if (args.length() != 0)
+        return ErrorBadArgs(cx);
 
     RetElem result[Vret::lanes];
-    for (int32_t i = 0; i < Vret::lanes; i++)
+    for (unsigned i = 0; i < Vret::lanes; i++)
         result[i] = RetElem(0);
 
     RootedObject obj(cx, Create<Vret>(cx, result));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
     return true;
@@ -778,27 +755,25 @@ FuncZero(JSContext *cx, unsigned argc, V
 
 template<typename Vret>
 static bool
 FuncSplat(JSContext *cx, unsigned argc, Value *vp)
 {
     typedef typename Vret::Elem RetElem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 1 || !args[0].isNumber()) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
-    }
+    if (args.length() != 1 || !args[0].isNumber())
+        return ErrorBadArgs(cx);
 
     RetElem arg;
     if (!Vret::toType(cx, args[0], &arg))
         return false;
 
     RetElem result[Vret::lanes];
-    for (int32_t i = 0; i < Vret::lanes; i++)
+    for (unsigned i = 0; i < Vret::lanes; i++)
         result[i] = arg;
 
     RootedObject obj(cx, Create<Vret>(cx, result));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
     return true;
@@ -807,22 +782,21 @@ FuncSplat(JSContext *cx, unsigned argc, 
 static bool
 Int32x4Bool(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 4 ||
         !args[0].isBoolean() || !args[1].isBoolean() ||
         !args[2].isBoolean() || !args[3].isBoolean())
     {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
+        return ErrorBadArgs(cx);
     }
 
     int32_t result[Int32x4::lanes];
-    for (int32_t i = 0; i < Int32x4::lanes; i++)
+    for (unsigned i = 0; i < Int32x4::lanes; i++)
         result[i] = args[i].toBoolean() ? 0xFFFFFFFF : 0x0;
 
     RootedObject obj(cx, Create<Int32x4>(cx, result));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
     return true;
@@ -830,26 +804,25 @@ Int32x4Bool(JSContext *cx, unsigned argc
 
 static bool
 Float32x4Clamp(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 3 || !IsVectorObject<Float32x4>(args[0]) ||
         !IsVectorObject<Float32x4>(args[1]) || !IsVectorObject<Float32x4>(args[2]))
     {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
+        return ErrorBadArgs(cx);
     }
 
     float *val = TypedObjectMemory<float *>(args[0]);
     float *lowerLimit = TypedObjectMemory<float *>(args[1]);
     float *upperLimit = TypedObjectMemory<float *>(args[2]);
 
     float result[Float32x4::lanes];
-    for (int32_t i = 0; i < Float32x4::lanes; i++) {
+    for (unsigned i = 0; i < Float32x4::lanes; i++) {
         result[i] = val[i] < lowerLimit[i] ? lowerLimit[i] : val[i];
         result[i] = result[i] > upperLimit[i] ? upperLimit[i] : result[i];
     }
 
     RootedObject obj(cx, Create<Float32x4>(cx, result));
     if (!obj)
         return false;
 
@@ -859,34 +832,33 @@ Float32x4Clamp(JSContext *cx, unsigned a
 
 static bool
 Int32x4Select(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 3 || !IsVectorObject<Int32x4>(args[0]) ||
         !IsVectorObject<Float32x4>(args[1]) || !IsVectorObject<Float32x4>(args[2]))
     {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-        return false;
+        return ErrorBadArgs(cx);
     }
 
     int32_t *val = TypedObjectMemory<int32_t *>(args[0]);
     int32_t *tv = TypedObjectMemory<int32_t *>(args[1]);
     int32_t *fv = TypedObjectMemory<int32_t *>(args[2]);
 
     int32_t tr[Int32x4::lanes];
-    for (int32_t i = 0; i < Int32x4::lanes; i++)
+    for (unsigned i = 0; i < Int32x4::lanes; i++)
         tr[i] = And<int32_t, Int32x4>::apply(val[i], tv[i]);
 
     int32_t fr[Int32x4::lanes];
-    for (int32_t i = 0; i < Int32x4::lanes; i++)
+    for (unsigned i = 0; i < Int32x4::lanes; i++)
         fr[i] = And<int32_t, Int32x4>::apply(Not<int32_t, Int32x4>::apply(val[i], 0), fv[i]);
 
     int32_t orInt[Int32x4::lanes];
-    for (int32_t i = 0; i < Int32x4::lanes; i++)
+    for (unsigned i = 0; i < Int32x4::lanes; i++)
         orInt[i] = Or<int32_t, Int32x4>::apply(tr[i], fr[i]);
 
     float *result = reinterpret_cast<float *>(orInt);
     RootedObject obj(cx, Create<Float32x4>(cx, result));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
--- a/js/src/builtin/SIMD.h
+++ b/js/src/builtin/SIMD.h
@@ -111,17 +111,17 @@ class SIMDObject : public JSObject
     static JSObject* initClass(JSContext *cx, Handle<GlobalObject *> global);
     static bool toString(JSContext *cx, unsigned int argc, jsval *vp);
 };
 
 // These classes exist for use with templates below.
 
 struct Float32x4 {
     typedef float Elem;
-    static const int32_t lanes = 4;
+    static const unsigned lanes = 4;
     static const X4TypeDescr::Type type = X4TypeDescr::TYPE_FLOAT32;
 
     static TypeDescr &GetTypeDescr(GlobalObject &global) {
         return global.float32x4TypeDescr().as<TypeDescr>();
     }
     static Elem toType(Elem a) {
         return a;
     }
@@ -131,17 +131,17 @@ struct Float32x4 {
     }
     static void setReturn(CallArgs &args, Elem value) {
         args.rval().setDouble(JS::CanonicalizeNaN(value));
     }
 };
 
 struct Int32x4 {
     typedef int32_t Elem;
-    static const int32_t lanes = 4;
+    static const unsigned lanes = 4;
     static const X4TypeDescr::Type type = X4TypeDescr::TYPE_INT32;
 
     static TypeDescr &GetTypeDescr(GlobalObject &global) {
         return global.int32x4TypeDescr().as<TypeDescr>();
     }
     static Elem toType(Elem a) {
         return ToInt32(a);
     }