Bug 898494 - Fix lack of rooting in Binary Data. r=nmatsakis
authorNikhil Marathe <nsm.nikhil@gmail.com>
Mon, 29 Jul 2013 10:22:11 -0700
changeset 140375 bf208ba34b9c8ac2544ee0c055e3ce23f9cc2fcc
parent 140374 6db27e6a073955e872981caf3f0b1554871e1511
child 140376 0da6dd57126350e4bab8bc047897ed0b9a1f20af
push id31708
push usernsm.nikhil@gmail.com
push dateMon, 29 Jul 2013 17:30:47 +0000
treeherdermozilla-inbound@4e20058bb808 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnmatsakis
bugs898494
milestone25.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 898494 - Fix lack of rooting in Binary Data. r=nmatsakis
js/src/builtin/BinaryData.cpp
--- a/js/src/builtin/BinaryData.cpp
+++ b/js/src/builtin/BinaryData.cpp
@@ -53,37 +53,37 @@ TypeThrowError(JSContext *cx, unsigned a
 
 static JSBool
 DataThrowError(JSContext *cx, unsigned argc, Value *vp)
 {
     return ReportIsNotFunction(cx, *vp);
 }
 
 static void
-ReportTypeError(JSContext *cx, Value fromValue, const char *toType)
+ReportTypeError(JSContext *cx, HandleValue fromValue, const char *toType)
 {
     char *valueStr = JS_EncodeString(cx, JS_ValueToString(cx, fromValue));
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
                          valueStr, toType);
     JS_free(cx, (void *) valueStr);
 }
 
 static void
-ReportTypeError(JSContext *cx, Value fromValue, JSString *toType)
+ReportTypeError(JSContext *cx, HandleValue fromValue, JSString *toType)
 {
     const char *fnName = JS_EncodeString(cx, toType);
     ReportTypeError(cx, fromValue, fnName);
     JS_free(cx, (void *) fnName);
 }
 
 // The false return value allows callers to just return as soon as this is
 // called.
 // So yes this call is with side effects.
 static bool
-ReportTypeError(JSContext *cx, Value fromValue, HandleObject exemplar)
+ReportTypeError(JSContext *cx, HandleValue fromValue, HandleObject exemplar)
 {
     RootedValue v(cx, ObjectValue(*exemplar));
     ReportTypeError(cx, fromValue, ToString<CanGC>(cx, v));
     return false;
 }
 
 static int32_t
 Clamp(int32_t value, int32_t min, int32_t max)
@@ -672,20 +672,21 @@ ArrayType::create(JSContext *cx, HandleO
      * the actual size in terms of memory layout, it is
      * always elementType.bytes * length */
     RootedValue typeBytes(cx, NumberValue(elementTypeBytes.toInt32() * length));
     if (!JSObject::defineProperty(cx, obj, cx->names().bytes,
                                   typeBytes,
                                   NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT))
         return NULL;
 
-    obj->setFixedSlot(SLOT_MEMSIZE,
-                      Int32Value(::GetMemSize(cx, elementType) * length));
+    RootedValue slotMemsizeVal(cx, Int32Value(::GetMemSize(cx, elementType) * length));
+    obj->setFixedSlot(SLOT_MEMSIZE, slotMemsizeVal);
 
-    obj->setFixedSlot(SLOT_ALIGN, Int32Value(::GetAlign(cx, elementType)));
+    RootedValue slotAlignVal(cx, Int32Value(::GetAlign(cx, elementType)));
+    obj->setFixedSlot(SLOT_ALIGN, slotAlignVal);
 
     RootedObject prototypeObj(cx,
         SetupAndGetPrototypeObjectForComplexTypeInstance(cx, arrayTypeGlobal));
 
     if (!prototypeObj)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, obj, prototypeObj))
@@ -764,17 +765,18 @@ DataInstanceUpdate(JSContext *cx, unsign
         JS_ReportErrorNumber(cx, js_GetErrorMessage,
                              NULL, JSMSG_MORE_ARGS_NEEDED,
                              "update()", "0", "s");
         return false;
     }
 
     RootedObject thisObj(cx, args.thisv().toObjectOrNull());
     if (!IsBlock(thisObj)) {
-        ReportTypeError(cx, ObjectValue(*thisObj), "BinaryData block");
+        RootedValue thisObjVal(cx, ObjectValue(*thisObj));
+        ReportTypeError(cx, thisObjVal, "BinaryData block");
         return false;
     }
 
     RootedValue val(cx, args[0]);
     uint8_t *memory = (uint8_t*) thisObj->getPrivate();
     RootedObject type(cx, GetType(thisObj));
     if (!ConvertAndCopyTo(cx, type, val, memory)) {
         ReportTypeError(cx, val, type);
@@ -820,18 +822,18 @@ ArrayType::repeat(JSContext *cx, unsigne
         JS_ReportErrorNumber(cx, js_GetErrorMessage,
                              NULL, JSMSG_MORE_ARGS_NEEDED,
                              "repeat()", "0", "s");
         return false;
     }
 
     RootedObject thisObj(cx, args.thisv().toObjectOrNull());
     if (!IsArrayType(thisObj)) {
-        JSString *valueStr = JS_ValueToString(cx, args.thisv());
         char *valueChars = const_cast<char*>("(unknown type)");
+        RootedString valueStr(cx, JS_ValueToString(cx, args.thisv()));
         if (valueStr)
             valueChars = JS_EncodeString(cx, valueStr);
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, "ArrayType", "repeat", valueChars);
         if (valueStr)
             JS_free(cx, valueChars);
         return false;
     }
 
@@ -894,49 +896,49 @@ BinaryArray::createEmpty(JSContext *cx, 
     obj->setFixedSlot(SLOT_DATATYPE, ObjectValue(*type));
     obj->setFixedSlot(SLOT_BLOCKREFOWNER, NullValue());
     return obj;
 }
 
 JSObject *
 BinaryArray::create(JSContext *cx, HandleObject type)
 {
-    JSObject *obj = createEmpty(cx, type);
+    RootedObject obj(cx, createEmpty(cx, type));
     if (!obj)
         return NULL;
 
     int32_t memsize = GetMemSize(cx, type);
     void *memory = JS_malloc(cx, memsize);
     if (!memory)
         return NULL;
     memset(memory, 0, memsize);
     obj->setPrivate(memory);
     return obj;
 }
 
 JSObject *
 BinaryArray::create(JSContext *cx, HandleObject type, HandleValue initial)
 {
-    JSObject *obj = create(cx, type);
+    RootedObject obj(cx, create(cx, type));
     if (!obj)
         return NULL;
 
     uint8_t *memory = (uint8_t*) obj->getPrivate();
     if (!ConvertAndCopyTo(cx, type, initial, memory))
         return NULL;
 
     return obj;
 }
 
 JSObject *
 BinaryArray::create(JSContext *cx, HandleObject type,
                     HandleObject owner, size_t offset)
 {
     JS_ASSERT(IsBlock(owner));
-    JSObject *obj = createEmpty(cx, type);
+    RootedObject obj(cx, createEmpty(cx, type));
     if (!obj)
         return NULL;
 
     obj->setPrivate(((uint8_t *) owner->getPrivate()) + offset);
     obj->setFixedSlot(SLOT_BLOCKREFOWNER, ObjectValue(*owner));
     return obj;
 }
 
@@ -1029,17 +1031,18 @@ JSBool BinaryArray::subarray(JSContext *
     if (!args[0].isInt32()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_BINARYDATA_SUBARRAY_INTEGER_ARG, "1");
         return false;
     }
 
     RootedObject thisObj(cx, &args.thisv().toObject());
     if (!IsBinaryArray(thisObj)) {
-        ReportTypeError(cx, ObjectValue(*thisObj), "binary array");
+        RootedValue thisObjVal(cx, ObjectValue(*thisObj));
+        ReportTypeError(cx, thisObjVal, "binary array");
         return false;
     }
 
     RootedObject type(cx, GetType(thisObj));
     RootedObject elementType(cx, ArrayType::elementType(cx, type));
     uint32_t length = ArrayType::length(cx, type);
 
     int32_t begin = args[0].toInt32();
@@ -1099,27 +1102,29 @@ BinaryArray::fill(JSContext *cx, unsigne
         return false;
     }
 
     if (!args.thisv().isObject())
         return false;
 
     RootedObject thisObj(cx, args.thisv().toObjectOrNull());
     if (!IsBinaryArray(thisObj)) {
-        ReportTypeError(cx, ObjectValue(*thisObj), "binary array");
+        RootedValue thisObjVal(cx, ObjectValue(*thisObj));
+        ReportTypeError(cx, thisObjVal, "binary array");
         return false;
     }
 
     Value funArrayTypeVal = GetFunctionNativeReserved(&args.callee(), 0);
     JS_ASSERT(funArrayTypeVal.isObject());
 
     RootedObject type(cx, GetType(thisObj));
     RootedObject funArrayType(cx, funArrayTypeVal.toObjectOrNull());
     if (!IsSameBinaryDataType(cx, funArrayType, type)) {
-        ReportTypeError(cx, ObjectValue(*thisObj), funArrayType);
+        RootedValue thisObjVal(cx, ObjectValue(*thisObj));
+        ReportTypeError(cx, thisObjVal, funArrayType);
         return false;
     }
 
     args.rval().setUndefined();
     RootedValue val(cx, args[0]);
     return FillBinaryArrayWithValue(cx, thisObj, val);
 }
 
@@ -1631,17 +1636,18 @@ JSObject *
 StructType::create(JSContext *cx, HandleObject structTypeGlobal,
                    HandleObject fields)
 {
     RootedObject obj(cx, NewBuiltinClassInstance(cx, &StructType::class_));
     if (!obj)
         return NULL;
 
     if (!StructType::layout(cx, obj, fields)) {
-        ReportTypeError(cx, ObjectValue(*fields), "StructType field specifier");
+        RootedValue fieldsVal(cx, ObjectValue(*fields));
+        ReportTypeError(cx, fieldsVal, "StructType field specifier");
         return NULL;
     }
 
     RootedObject fieldsProto(cx);
     if (!JSObject::getProto(cx, fields, &fieldsProto))
         return NULL;
 
     RootedObject clone(cx, CloneObject(cx, fields, fieldsProto, NullPtr()));
@@ -1727,19 +1733,19 @@ StructType::toString(JSContext *cx, unsi
 
     for (FieldList::const_iterator it = fieldList->begin(); it != fieldList->end(); ++it) {
         if (it != fieldList->begin())
             contents.append(", ");
 
         contents.append(IdToString(cx, it->name));
         contents.append(": ");
 
-        Value fieldStringVal;
+        RootedValue fieldStringVal(cx);
         if (!JS_CallFunctionName(cx, it->type,
-                                 "toString", 0, NULL, &fieldStringVal))
+                                 "toString", 0, NULL, fieldStringVal.address()))
             return false;
 
         contents.append(fieldStringVal.toString());
     }
 
     contents.append("})");
 
     args.rval().setString(contents.finishString());
@@ -1764,17 +1770,17 @@ BinaryStruct::createEmpty(JSContext *cx,
     obj->setFixedSlot(SLOT_DATATYPE, ObjectValue(*type));
     obj->setFixedSlot(SLOT_BLOCKREFOWNER, NullValue());
     return obj;
 }
 
 JSObject *
 BinaryStruct::create(JSContext *cx, HandleObject type)
 {
-    JSObject *obj = createEmpty(cx, type);
+    RootedObject obj(cx, createEmpty(cx, type));
     if (!obj)
         return NULL;
 
     int32_t memsize = GetMemSize(cx, type);
     void *memory = JS_malloc(cx, memsize);
     if (!memory)
         return NULL;
     memset(memory, 0, memsize);
@@ -1782,17 +1788,17 @@ BinaryStruct::create(JSContext *cx, Hand
     return obj;
 }
 
 JSObject *
 BinaryStruct::create(JSContext *cx, HandleObject type,
                      HandleObject owner, size_t offset)
 {
     JS_ASSERT(IsBlock(owner));
-    JSObject *obj = createEmpty(cx, type);
+    RootedObject obj(cx, createEmpty(cx, type));
     if (!obj)
         return NULL;
 
     obj->setPrivate(((uint8_t*) owner->getPrivate()) + offset);
     obj->setFixedSlot(SLOT_BLOCKREFOWNER, ObjectValue(*owner));
     return obj;
 }
 
@@ -1803,17 +1809,17 @@ BinaryStruct::construct(JSContext *cx, u
 
     RootedObject callee(cx, &args.callee());
 
     if (!IsStructType(callee)) {
         ReportTypeError(cx, args.calleev(), "is not an StructType");
         return false;
     }
 
-    JSObject *obj = create(cx, callee);
+    RootedObject obj(cx, create(cx, callee));
 
     if (obj)
         args.rval().setObject(*obj);
 
     return obj != NULL;
 }
 
 void
@@ -2230,17 +2236,17 @@ InitStructType(JSContext *cx, HandleObje
 }
 
 JSObject *
 js_InitBinaryDataClasses(JSContext *cx, HandleObject obj)
 {
     JS_ASSERT(obj->is<GlobalObject>());
     Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
 
-    JSObject *funProto = JS_GetFunctionPrototype(cx, global);
+    RootedObject funProto(cx, JS_GetFunctionPrototype(cx, global));
 #define BINARYDATA_NUMERIC_DEFINE(constant_, type_)\
     do {\
         RootedObject numFun(cx, JS_DefineObject(cx, global, #type_,\
                     (JSClass *) &NumericTypeClasses[constant_], funProto, 0));\
 \
         if (!numFun)\
             return NULL;\
 \