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 331022 4099b331a79a3466a939016f0715a75e3bf6a698
parent 331021 4012e45e502eebdea798846bfd2234aec4ccd6b2
child 331023 f5ca1d46b22ace7d9f1b3fe1f25a3ad0fcf5838f
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersefaust
bugs1259877
milestone48.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 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"))