Bug 1259877 - Update various builtins to use js::Call, not js::Invoke. r=efaust
authorJeff Walden <jwalden@mit.edu>
Tue, 22 Mar 2016 13:40:20 -0700
changeset 316925 4099b331a79a3466a939016f0715a75e3bf6a698
parent 316924 4012e45e502eebdea798846bfd2234aec4ccd6b2
child 316926 f5ca1d46b22ace7d9f1b3fe1f25a3ad0fcf5838f
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersefaust
bugs1259877
milestone48.0a1
Bug 1259877 - Update various builtins to use js::Call, not js::Invoke. r=efaust
js/src/builtin/MapObject.cpp
js/src/jsarray.cpp
js/src/jsdate.cpp
js/src/jsobj.cpp
js/src/json.cpp
js/src/jsstr.cpp
js/src/vm/TypedArrayObject.cpp
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -1470,33 +1470,28 @@ const JSFunctionSpec selfhosting_collect
 bool
 js::InitSelfHostingCollectionIteratorFunctions(JSContext* cx, HandleObject obj)
 {
     return DefineFunctions(cx, obj, selfhosting_collection_iterator_methods, AsIntrinsic);
 }
 
 /*** JS static utility functions *********************************************/
 
-static
-bool
+static bool
 forEach(const char* funcName, JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisArg)
 {
     CHECK_REQUEST(cx);
+
     RootedId forEachId(cx, NameToId(cx->names().forEach));
     RootedFunction forEachFunc(cx, JS::GetSelfHostedFunction(cx, funcName, forEachId, 2));
     if (!forEachFunc)
         return false;
-    InvokeArgs args(cx);
-    if (!args.init(2))
-        return false;
-    args.setCallee(JS::ObjectValue(*forEachFunc));
-    args.setThis(JS::ObjectValue(*obj));
-    args[0].set(callbackFn);
-    args[1].set(thisArg);
-    return Invoke(cx, args);
+
+    RootedValue fval(cx, ObjectValue(*forEachFunc));
+    return Call(cx, fval, obj, callbackFn, thisArg, &fval);
 }
 
 // Handles Clear/Size for public jsapi map/set access
 template<typename RetT>
 RetT
 CallObjFunc(RetT(*ObjFunc)(JSContext*, HandleObject), JSContext* cx, HandleObject obj)
 {
     CHECK_REQUEST(cx);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -1139,17 +1139,18 @@ ArrayJoinKernel(JSContext* cx, Separator
             bool hole;
             if (!GetElement(cx, obj, i, &hole, &v))
                 return false;
             if (!hole && !v.isNullOrUndefined()) {
                 if (Locale) {
                     RootedValue fun(cx);
                     if (!GetProperty(cx, v, cx->names().toLocaleString, &fun))
                         return false;
-                    if (!Invoke(cx, v, fun, 0, nullptr, &v))
+
+                    if (!Call(cx, fun, v, &v))
                         return false;
                 }
                 if (!ValueToStringBuffer(cx, v, sb))
                     return false;
             }
 
             if (++i != length && !sepOp(cx, sb))
                 return false;
@@ -1828,18 +1829,17 @@ SortNumerically(JSContext* cx, AutoValue
                           SortComparatorNumerics[comp], vec);
 }
 
 bool
 js::array_sort(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
-    RootedValue fvalRoot(cx);
-    Value& fval = fvalRoot.get();
+    RootedValue fval(cx);
 
     if (args.hasDefined(0)) {
         if (args[0].isPrimitive()) {
             JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_SORT_ARG);
             return false;
         }
         fval = args[0];     /* non-default compare function */
     } else {
@@ -1866,30 +1866,17 @@ js::array_sort(JSContext* cx, unsigned a
         if (!GlobalObject::getIntrinsicValue(cx, cx->global(), selfHostedSortName,
             &selfHostedSortValue)) {
             return false;
         }
 
         MOZ_ASSERT(selfHostedSortValue.isObject());
         MOZ_ASSERT(selfHostedSortValue.toObject().is<JSFunction>());
 
-        InvokeArgs iargs(cx);
-
-        if (!iargs.init(1))
-            return false;
-
-        iargs.setCallee(selfHostedSortValue);
-        iargs.setThis(args.thisv());
-        iargs[0].set(fval);
-
-        if (!Invoke(cx, iargs))
-            return false;
-
-        args.rval().set(iargs.rval());
-        return true;
+        return Call(cx, selfHostedSortValue, args.thisv(), fval, args.rval());
     }
 
     uint32_t len;
     if (!GetLengthProperty(cx, obj, &len))
         return false;
     if (len < 2) {
         /* [] and [a] remain unchanged when sorted. */
         args.rval().setObject(*obj);
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -2548,27 +2548,17 @@ date_toJSON(JSContext* cx, unsigned argc
     /* Step 5. */
     if (!IsCallable(toISO)) {
         JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js::GetErrorMessage, nullptr,
                                      JSMSG_BAD_TOISOSTRING_PROP);
         return false;
     }
 
     /* Step 6. */
-    InvokeArgs args2(cx);
-    if (!args2.init(0))
-        return false;
-
-    args2.setCallee(toISO);
-    args2.setThis(ObjectValue(*obj));
-
-    if (!Invoke(cx, args2))
-        return false;
-    args.rval().set(args2.rval());
-    return true;
+    return Call(cx, toISO, obj, args.rval());
 }
 
 /* for Date.toLocaleFormat; interface to PRMJTime date struct.
  */
 static void
 new_explode(double timeval, PRMJTime* split)
 {
     double year = YearFromTime(timeval);
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3012,17 +3012,18 @@ static bool
 MaybeCallMethod(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
 {
     if (!GetProperty(cx, obj, obj, id, vp))
         return false;
     if (!IsCallable(vp)) {
         vp.setObject(*obj);
         return true;
     }
-    return Invoke(cx, ObjectValue(*obj), vp, 0, nullptr, vp);
+
+    return js::Call(cx, vp, obj, vp);
 }
 
 static bool
 ReportCantConvert(JSContext* cx, unsigned errorNumber, HandleObject obj, JSType hint)
 {
     const Class* clasp = obj->getClass();
 
     // Avoid recursive death when decompiling in ReportValueError.
@@ -3122,28 +3123,29 @@ js::ToPrimitiveSlow(JSContext* cx, JSTyp
     // Steps 4-5.
     RootedId id(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().toPrimitive));
     RootedValue method(cx);
     if (!GetProperty(cx, obj, obj, id, &method))
         return false;
 
     // Step 6.
     if (!method.isUndefined()) {
-        // Step 6 of GetMethod. Invoke() below would do this check and throw a
+        // Step 6 of GetMethod. js::Call() below would do this check and throw a
         // TypeError anyway, but this produces a better error message.
         if (!IsCallable(method))
             return ReportCantConvert(cx, JSMSG_TOPRIMITIVE_NOT_CALLABLE, obj, preferredType);
 
-        // Steps 1-3.
-        RootedValue hint(cx, StringValue(preferredType == JSTYPE_STRING ? cx->names().string :
-                                         preferredType == JSTYPE_NUMBER ? cx->names().number :
-                                         cx->names().default_));
-
-        // Steps 6.a-b.
-        if (!Invoke(cx, vp, method, 1, hint.address(), vp))
+        // Steps 1-3, 6.a-b.
+        RootedValue arg0(cx, StringValue(preferredType == JSTYPE_STRING
+                                         ? cx->names().string
+                                         : preferredType == JSTYPE_NUMBER
+                                         ? cx->names().number
+                                         : cx->names().default_));
+
+        if (!js::Call(cx, method, vp, arg0, vp))
             return false;
 
         // Steps 6.c-d.
         if (vp.isObject())
             return ReportCantConvert(cx, JSMSG_TOPRIMITIVE_RETURNED_OBJECT, obj, preferredType);
         return true;
     }
 
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -232,50 +232,34 @@ PreprocessValue(JSContext* cx, HandleObj
         if (!GetProperty(cx, obj, obj, cx->names().toJSON, &toJSON))
             return false;
 
         if (IsCallable(toJSON)) {
             keyStr = KeyStringifier<KeyType>::toString(cx, key);
             if (!keyStr)
                 return false;
 
-            InvokeArgs args(cx);
-            if (!args.init(1))
+            RootedValue arg0(cx, StringValue(keyStr));
+            if (!js::Call(cx, toJSON, vp, arg0, vp))
                 return false;
-
-            args.setCallee(toJSON);
-            args.setThis(vp);
-            args[0].setString(keyStr);
-
-            if (!Invoke(cx, args))
-                return false;
-            vp.set(args.rval());
         }
     }
 
     /* Step 3. */
     if (scx->replacer && scx->replacer->isCallable()) {
         if (!keyStr) {
             keyStr = KeyStringifier<KeyType>::toString(cx, key);
             if (!keyStr)
                 return false;
         }
 
-        InvokeArgs args(cx);
-        if (!args.init(2))
+        RootedValue arg0(cx, StringValue(keyStr));
+        RootedValue replacerVal(cx, ObjectValue(*scx->replacer));
+        if (!js::Call(cx, replacerVal, holder, arg0, vp, vp))
             return false;
-
-        args.setCallee(ObjectValue(*scx->replacer));
-        args.setThis(ObjectValue(*holder));
-        args[0].setString(keyStr);
-        args[1].set(vp);
-
-        if (!Invoke(cx, args))
-            return false;
-        vp.set(args.rval());
     }
 
     /* Step 4. */
     if (vp.get().isObject()) {
         RootedObject obj(cx, &vp.get().toObject());
 
         ESClassValue cls;
         if (!GetBuiltinClass(cx, obj, &cls))
@@ -843,29 +827,18 @@ Walk(JSContext* cx, HandleObject holder,
         }
     }
 
     /* Step 3. */
     RootedString key(cx, IdToString(cx, name));
     if (!key)
         return false;
 
-    InvokeArgs args(cx);
-    if (!args.init(2))
-        return false;
-
-    args.setCallee(reviver);
-    args.setThis(ObjectValue(*holder));
-    args[0].setString(key);
-    args[1].set(val);
-
-    if (!Invoke(cx, args))
-        return false;
-    vp.set(args.rval());
-    return true;
+    RootedValue keyVal(cx, StringValue(key));
+    return js::Call(cx, reviver, holder, keyVal, val, vp);
 }
 
 static bool
 Revive(JSContext* cx, HandleValue reviver, MutableHandleValue vp)
 {
     RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!obj)
         return false;
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -2888,20 +2888,21 @@ js::ValueToSource(JSContext* cx, HandleV
         return ToString<CanGC>(cx, v);
     }
 
     RootedValue fval(cx);
     RootedObject obj(cx, &v.toObject());
     if (!GetProperty(cx, obj, obj, cx->names().toSource, &fval))
         return nullptr;
     if (IsCallable(fval)) {
-        RootedValue rval(cx);
-        if (!Invoke(cx, ObjectValue(*obj), fval, 0, nullptr, &rval))
+        RootedValue v(cx);
+        if (!js::Call(cx, fval, obj, &v))
             return nullptr;
-        return ToString<CanGC>(cx, rval);
+
+        return ToString<CanGC>(cx, v);
     }
 
     return ObjectToSource(cx, obj);
 }
 
 JSString*
 js::StringToSource(JSContext* cx, JSString* str)
 {
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -564,29 +564,29 @@ class TypedArrayObjectTemplate : public 
                  */
 
                 RootedObject protoRoot(cx, proto);
                 if (!protoRoot) {
                     if (!GetBuiltinPrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()), &protoRoot))
                         return nullptr;
                 }
 
-                InvokeArgs args(cx);
-                if (!args.init(3))
-                    return nullptr;
-
-                args.setCallee(cx->compartment()->maybeGlobal()->createArrayFromBuffer<NativeType>());
-                args.setThis(ObjectValue(*bufobj));
+                FixedInvokeArgs<3> args(cx);
+
                 args[0].setNumber(byteOffset);
                 args[1].setInt32(lengthInt);
                 args[2].setObject(*protoRoot);
 
-                if (!Invoke(cx, args))
+                RootedValue fval(cx, cx->global()->createArrayFromBuffer<NativeType>());
+                RootedValue thisv(cx, ObjectValue(*bufobj));
+                RootedValue rval(cx);
+                if (!js::Call(cx, fval, thisv, args, &rval))
                     return nullptr;
-                return &args.rval().toObject();
+
+                return &rval.toObject();
             }
         }
 
         if (!IsArrayBuffer(bufobj) && !IsSharedArrayBuffer(bufobj)) {
             JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
             return nullptr; // must be arrayBuffer
         }
 
@@ -1452,28 +1452,25 @@ DataViewObject::constructWrapped(JSConte
 
     Rooted<GlobalObject*> global(cx, cx->compartment()->maybeGlobal());
     if (!proto) {
         proto = global->getOrCreateDataViewPrototype(cx);
         if (!proto)
             return false;
     }
 
-    InvokeArgs args2(cx);
-    if (!args2.init(3))
-        return false;
-    args2.setCallee(global->createDataViewForThis());
-    args2.setThis(ObjectValue(*bufobj));
+    FixedInvokeArgs<3> args2(cx);
+
     args2[0].set(PrivateUint32Value(byteOffset));
     args2[1].set(PrivateUint32Value(byteLength));
     args2[2].setObject(*proto);
-    if (!Invoke(cx, args2))
-        return false;
-    args.rval().set(args2.rval());
-    return true;
+
+    RootedValue fval(cx, global->createDataViewForThis());
+    RootedValue thisv(cx, ObjectValue(*bufobj));
+    return js::Call(cx, fval, thisv, args2, args.rval());
 }
 
 bool
 DataViewObject::class_constructor(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     if (!ThrowIfNotConstructing(cx, args, "DataView"))