author | Tom Schuster <evilpies@gmail.com> |
Wed, 07 Mar 2018 14:35:22 +0100 | |
changeset 410241 | 9a6a2971bce35bfd3b3be8793b08e4d67fb904d3 |
parent 410240 | 16d254b2fe0d46094d86752ec144ba8c2c162046 |
child 410242 | 323f339c6353360d685452a20f6146018a4dabb6 |
push id | 33723 |
push user | ebalazs@mozilla.com |
push date | Tue, 27 Mar 2018 21:48:41 +0000 |
treeherder | mozilla-central@56d6db4ad38c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bz |
bugs | 1255800 |
milestone | 61.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
|
--- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1211,23 +1211,24 @@ InitIds(JSContext* cx, const NativePrope } #undef INIT_IDS_IF_DEFINED bool QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JS::Rooted<JS::Value> thisv(cx, JS_THIS(cx, vp)); - if (thisv.isNull()) + if (!args.thisv().isObject()) { + JS_ReportErrorASCII(cx, "QueryInterface called on incompatible non-object"); return false; + } // Get the object. It might be a security wrapper, in which case we do a checked // unwrap. - JS::Rooted<JSObject*> origObj(cx, &thisv.toObject()); + JS::Rooted<JSObject*> origObj(cx, &args.thisv().toObject()); JS::Rooted<JSObject*> obj(cx, js::CheckedUnwrap(origObj, /* stopAtWindowProxy = */ false)); if (!obj) { JS_ReportErrorASCII(cx, "Permission denied to access object"); return false; } // Switch this to UnwrapDOMObjectToISupports once our global objects are @@ -1264,17 +1265,17 @@ QueryInterface(JSContext* cx, unsigned a } nsCOMPtr<nsISupports> unused; nsresult rv = native->QueryInterface(*iid->GetID(), getter_AddRefs(unused)); if (NS_FAILED(rv)) { return Throw(cx, rv); } - *vp = thisv; + args.rval().set(args.thisv()); return true; } void GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor, nsWrapperCache* aCache, nsIJSID* aIID, JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError) {
--- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -1595,20 +1595,21 @@ CallNPMethodInternal(JSContext *cx, JS:: return ReportExceptionIfPending(cx); } static bool CallNPMethod(JSContext *cx, unsigned argc, JS::Value *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp)); - if (!obj) - return false; - + if (!args.thisv().isObject()) { + ThrowJSExceptionASCII(cx, "plug-in method called on incompatible non-object"); + return false; + } + JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject()); return CallNPMethodInternal(cx, obj, args.length(), args.array(), vp, false); } bool NPObjWrapperProxyHandler::getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc) const {
--- a/ipc/testshell/XPCShellEnvironment.cpp +++ b/ipc/testshell/XPCShellEnvironment.cpp @@ -127,21 +127,18 @@ Dump(JSContext *cx, unsigned argc, JS::V static bool Load(JSContext *cx, unsigned argc, JS::Value *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp)); - if (!obj) - return false; - - if (!JS_IsGlobalObject(obj)) { + JS::RootedValue thisv(cx, args.computeThis(cx)); + if (!thisv.isObject() || !JS_IsGlobalObject(&thisv.toObject())) { JS_ReportErrorASCII(cx, "Trying to load() into a non-global object"); return false; } for (unsigned i = 0; i < args.length(); i++) { JS::Rooted<JSString*> str(cx, JS::ToString(cx, args[i])); if (!str) return false;
--- a/js/xpconnect/src/ExportHelpers.cpp +++ b/js/xpconnect/src/ExportHelpers.cpp @@ -283,40 +283,42 @@ FunctionForwarder(JSContext* cx, unsigne FunctionForwarderOptions options(cx, optionsObj); if (!options.Parse()) return false; // Grab and unwrap the underlying callable. RootedValue v(cx, js::GetFunctionNativeReserved(&args.callee(), 0)); RootedObject unwrappedFun(cx, js::UncheckedUnwrap(&v.toObject())); - RootedObject thisObj(cx, args.isConstructing() ? nullptr : JS_THIS_OBJECT(cx, vp)); + RootedValue thisVal(cx, NullValue()); + if (!args.isConstructing()) { + thisVal.set(args.computeThis(cx)); + } + { // We manually implement the contents of CrossCompartmentWrapper::call // here, because certain function wrappers (notably content->nsEP) are // not callable. JSAutoCompartment ac(cx, unwrappedFun); - - RootedValue thisVal(cx, ObjectOrNullValue(thisObj)); - if (!CheckSameOriginArg(cx, options, thisVal) || !JS_WrapObject(cx, &thisObj)) + if (!CheckSameOriginArg(cx, options, thisVal) || !JS_WrapValue(cx, &thisVal)) return false; for (size_t n = 0; n < args.length(); ++n) { if (!CheckSameOriginArg(cx, options, args[n]) || !JS_WrapValue(cx, args[n])) return false; } RootedValue fval(cx, ObjectValue(*unwrappedFun)); if (args.isConstructing()) { RootedObject obj(cx); if (!JS::Construct(cx, fval, args, &obj)) return false; args.rval().setObject(*obj); } else { - if (!JS_CallFunctionValue(cx, thisObj, fval, args, args.rval())) + if (!JS::Call(cx, thisVal, fval, args, args.rval())) return false; } } // Rewrap the return value into our compartment. return JS_WrapValue(cx, args.rval()); }
--- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -210,21 +210,23 @@ SandboxImport(JSContext* cx, unsigned ar JS_MarkCrossZoneIdValue(cx, StringValue(funname)); RootedId id(cx); if (!JS_StringToId(cx, funname, &id)) return false; // We need to resolve the this object, because this function is used // unbound and should still work and act on the original sandbox. - RootedObject thisObject(cx, JS_THIS_OBJECT(cx, vp)); - if (!thisObject) { + + RootedValue thisv(cx, args.computeThis(cx)); + if (!thisv.isObject()) { XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx); return false; } + RootedObject thisObject(cx, &thisv.toObject()); if (!JS_SetPropertyById(cx, thisObject, id, args[0])) return false; args.rval().setUndefined(); return true; } static bool
--- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -332,21 +332,18 @@ Dump(JSContext* cx, unsigned argc, Value return true; } static bool Load(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp)); - if (!obj) - return false; - - if (!JS_IsGlobalObject(obj)) { + RootedValue thisv(cx, args.computeThis(cx)); + if (!thisv.isObject() || !JS_IsGlobalObject(&thisv.toObject())) { JS_ReportErrorASCII(cx, "Trying to load() into a non-global object"); return false; } RootedString str(cx); for (unsigned i = 0; i < args.length(); i++) { str = ToString(cx, args[i]); if (!str)
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp +++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp @@ -64,19 +64,23 @@ ToStringGuts(XPCCallContext& ccx) } /***************************************************************************/ static bool XPC_WN_Shared_ToString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); - if (!obj) + + RootedValue thisv(cx, args.computeThis(cx)); + if (!thisv.isObject()) { + JS_ReportErrorASCII(cx, "Called on incompatible |this|"); return false; + } + RootedObject obj(cx, &thisv.toObject()); XPCCallContext ccx(cx, obj); if (!ccx.IsValid()) return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); ccx.SetName(ccx.GetContext()->GetStringID(XPCJSContext::IDX_TO_STRING)); ccx.SetArgsAndResultPtr(args.length(), args.array(), vp); return ToStringGuts(ccx); } @@ -171,19 +175,21 @@ GetDoubleWrappedJSObject(XPCCallContext& // This is the getter native function we use to handle 'wrappedJSObject' for // double wrapped JSObjects. static bool XPC_WN_DoubleWrappedGetter(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); - if (!obj) + if (!args.thisv().isObject()) { + JS_ReportErrorASCII(cx, "xpconnect double wrapped getter called on incompatible non-object"); return false; + } + RootedObject obj(cx, &args.thisv().toObject()); XPCCallContext ccx(cx, obj); XPCWrappedNative* wrapper = ccx.GetWrapper(); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); MOZ_ASSERT(JS_TypeOfValue(cx, args.calleev()) == JSTYPE_FUNCTION, "bad function"); RootedObject realObject(cx, GetDoubleWrappedJSObject(ccx, wrapper)); @@ -889,19 +895,22 @@ FixUpThisIfBroken(JSObject* obj, JSObjec bool XPC_WN_CallMethod(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); MOZ_ASSERT(JS_TypeOfValue(cx, args.calleev()) == JSTYPE_FUNCTION, "bad function"); RootedObject funobj(cx, &args.callee()); - RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); - if (!obj) + RootedValue thisv(cx, args.computeThis(cx)); + if (!thisv.isObject()) { + JS_ReportErrorASCII(cx, "Called on incompatible |this|"); return false; + } + RootedObject obj(cx, &thisv.toObject()); obj = FixUpThisIfBroken(obj, funobj); XPCCallContext ccx(cx, obj, funobj, JSID_VOIDHANDLE, args.length(), args.array(), vp); XPCWrappedNative* wrapper = ccx.GetWrapper(); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); RefPtr<XPCNativeInterface> iface; @@ -915,19 +924,21 @@ XPC_WN_CallMethod(JSContext* cx, unsigne bool XPC_WN_GetterSetter(JSContext* cx, unsigned argc, Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); MOZ_ASSERT(JS_TypeOfValue(cx, args.calleev()) == JSTYPE_FUNCTION, "bad function"); RootedObject funobj(cx, &args.callee()); - RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); - if (!obj) + if (!args.thisv().isObject()) { + JS_ReportErrorASCII(cx, "xpconnect getter/setter called on incompatible non-object"); return false; + } + RootedObject obj(cx, &args.thisv().toObject()); obj = FixUpThisIfBroken(obj, funobj); XPCCallContext ccx(cx, obj, funobj, JSID_VOIDHANDLE, args.length(), args.array(), vp); XPCWrappedNative* wrapper = ccx.GetWrapper(); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); RefPtr<XPCNativeInterface> iface;
--- a/toolkit/components/telemetry/TelemetryHistogram.cpp +++ b/toolkit/components/telemetry/TelemetryHistogram.cpp @@ -1188,31 +1188,32 @@ internal_JSHistogram_CoerceValue(JSConte // If we're here then all type checks have passed and aValue contains the coerced integer return true; } bool internal_JSHistogram_Add(JSContext *cx, unsigned argc, JS::Value *vp) { - JSObject *obj = JS_THIS_OBJECT(cx, vp); - MOZ_ASSERT(obj); - if (!obj || - JS_GetClass(obj) != &sJSHistogramClass) { + JS::CallArgs args = CallArgsFromVp(argc, vp); + + if (!args.thisv().isObject() || + JS_GetClass(&args.thisv().toObject()) != &sJSHistogramClass) { JS_ReportErrorASCII(cx, "Wrong JS class, expected JSHistogram class"); return false; } + JSObject* obj = &args.thisv().toObject(); JSHistogramData* data = static_cast<JSHistogramData*>(JS_GetPrivate(obj)); MOZ_ASSERT(data); HistogramID id = data->histogramId; MOZ_ASSERT(internal_IsHistogramEnumId(id)); uint32_t type = gHistogramInfos[id].histogramType; - JS::CallArgs args = CallArgsFromVp(argc, vp); + // This function should always return |undefined| and never fail but // rather report failures using the console. args.rval().setUndefined(); // Special case of no arguments and count histogram type if (args.length() == 0) { if (!(type == nsITelemetry::HISTOGRAM_COUNT)) { LogToBrowserConsole(nsIScriptError::errorFlag, @@ -1286,23 +1287,24 @@ internal_JSHistogram_Add(JSContext *cx, return true; } bool internal_JSHistogram_Snapshot(JSContext *cx, unsigned argc, JS::Value *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JSObject *obj = JS_THIS_OBJECT(cx, vp); - if (!obj || - JS_GetClass(obj) != &sJSHistogramClass) { + + if (!args.thisv().isObject() || + JS_GetClass(&args.thisv().toObject()) != &sJSHistogramClass) { JS_ReportErrorASCII(cx, "Wrong JS class, expected JSHistogram class"); return false; } + JSObject* obj = &args.thisv().toObject(); JSHistogramData* data = static_cast<JSHistogramData*>(JS_GetPrivate(obj)); MOZ_ASSERT(data); HistogramID id = data->histogramId; Histogram* h = nullptr; Histogram::SampleSet ss; { StaticMutexAutoLock locker(gTelemetryHistogramMutex); @@ -1336,28 +1338,29 @@ internal_JSHistogram_Snapshot(JSContext } return true; } bool internal_JSHistogram_Clear(JSContext *cx, unsigned argc, JS::Value *vp) { - JSObject *obj = JS_THIS_OBJECT(cx, vp); - if (!obj || - JS_GetClass(obj) != &sJSHistogramClass) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + + if (!args.thisv().isObject() || + JS_GetClass(&args.thisv().toObject()) != &sJSHistogramClass) { JS_ReportErrorASCII(cx, "Wrong JS class, expected JSHistogram class"); return false; } + JSObject* obj = &args.thisv().toObject(); JSHistogramData* data = static_cast<JSHistogramData*>(JS_GetPrivate(obj)); MOZ_ASSERT(data); bool onlySubsession = false; - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); // This function should always return |undefined| and never fail but // rather report failures using the console. args.rval().setUndefined(); #if !defined(MOZ_WIDGET_ANDROID) if (args.length() >= 1) { if (!args[0].isBoolean()) { JS_ReportErrorASCII(cx, "Not a boolean"); @@ -1462,29 +1465,30 @@ static const JSClass sJSKeyedHistogramCl &sJSKeyedHistogramClassOps }; bool internal_KeyedHistogram_SnapshotImpl(JSContext *cx, unsigned argc, JS::Value *vp, bool subsession, bool clearSubsession) { - JSObject *obj = JS_THIS_OBJECT(cx, vp); - if (!obj || - JS_GetClass(obj) != &sJSKeyedHistogramClass) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + + if (!args.thisv().isObject() || + JS_GetClass(&args.thisv().toObject()) != &sJSKeyedHistogramClass) { JS_ReportErrorASCII(cx, "Wrong JS class, expected JSKeyedHistogram class"); return false; } + JSObject *obj = &args.thisv().toObject(); JSHistogramData* data = static_cast<JSHistogramData*>(JS_GetPrivate(obj)); MOZ_ASSERT(data); HistogramID id = data->histogramId; MOZ_ASSERT(internal_IsHistogramEnumId(id)); - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); // This function should always return |undefined| and never fail but // rather report failures using the console. args.rval().setUndefined(); // This is not good standard behavior given that we have histogram instances // covering multiple processes and two session types. // However, changing this requires some broader changes to callers. KeyedHistogram* keyed = internal_GetKeyedHistogramById(id, ProcessID::Parent, /* instantiate = */ true); @@ -1539,29 +1543,30 @@ internal_KeyedHistogram_SnapshotImpl(JSC } return true; } bool internal_JSKeyedHistogram_Add(JSContext *cx, unsigned argc, JS::Value *vp) { - JSObject *obj = JS_THIS_OBJECT(cx, vp); - if (!obj || - JS_GetClass(obj) != &sJSKeyedHistogramClass) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + + if (!args.thisv().isObject() || + JS_GetClass(&args.thisv().toObject()) != &sJSKeyedHistogramClass) { JS_ReportErrorASCII(cx, "Wrong JS class, expected JSKeyedHistogram class"); return false; } + JSObject *obj = &args.thisv().toObject(); JSHistogramData* data = static_cast<JSHistogramData*>(JS_GetPrivate(obj)); MOZ_ASSERT(data); HistogramID id = data->histogramId; MOZ_ASSERT(internal_IsHistogramEnumId(id)); - JS::CallArgs args = CallArgsFromVp(argc, vp); // This function should always return |undefined| and never fail but // rather report failures using the console. args.rval().setUndefined(); if (args.length() < 1) { LogToBrowserConsole(nsIScriptError::errorFlag, NS_LITERAL_STRING("Expected one argument")); return true; } @@ -1620,23 +1625,25 @@ internal_JSKeyedHistogram_Add(JSContext } return true; } bool internal_JSKeyedHistogram_Keys(JSContext *cx, unsigned argc, JS::Value *vp) { - JSObject *obj = JS_THIS_OBJECT(cx, vp); - if (!obj || - JS_GetClass(obj) != &sJSKeyedHistogramClass) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + + if (!args.thisv().isObject() || + JS_GetClass(&args.thisv().toObject()) != &sJSKeyedHistogramClass) { JS_ReportErrorASCII(cx, "Wrong JS class, expected JSKeyedHistogram class"); return false; } + JSObject *obj = &args.thisv().toObject(); JSHistogramData* data = static_cast<JSHistogramData*>(JS_GetPrivate(obj)); MOZ_ASSERT(data); HistogramID id = data->histogramId; KeyedHistogram* keyed = nullptr; { StaticMutexAutoLock locker(gTelemetryHistogramMutex); MOZ_ASSERT(internal_IsHistogramEnumId(id)); @@ -1647,17 +1654,16 @@ internal_JSKeyedHistogram_Keys(JSContext keyed = internal_GetKeyedHistogramById(id, ProcessID::Parent); } MOZ_ASSERT(keyed); if (!keyed) { return false; } - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); return NS_SUCCEEDED(keyed->GetJSKeys(cx, args)); } bool internal_JSKeyedHistogram_Snapshot(JSContext *cx, unsigned argc, JS::Value *vp) { return internal_KeyedHistogram_SnapshotImpl(cx, argc, vp, false, false); } @@ -1684,28 +1690,29 @@ internal_JSKeyedHistogram_SnapshotSubses return internal_KeyedHistogram_SnapshotImpl(cx, argc, vp, true, true); } #endif bool internal_JSKeyedHistogram_Clear(JSContext *cx, unsigned argc, JS::Value *vp) { - JSObject *obj = JS_THIS_OBJECT(cx, vp); - if (!obj || - JS_GetClass(obj) != &sJSKeyedHistogramClass) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + + if (!args.thisv().isObject() || + JS_GetClass(&args.thisv().toObject()) != &sJSKeyedHistogramClass) { JS_ReportErrorASCII(cx, "Wrong JS class, expected JSKeyedHistogram class"); return false; } + JSObject *obj = &args.thisv().toObject(); JSHistogramData* data = static_cast<JSHistogramData*>(JS_GetPrivate(obj)); MOZ_ASSERT(data); HistogramID id = data->histogramId; - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); // This function should always return |undefined| and never fail but // rather report failures using the console. args.rval().setUndefined(); bool onlySubsession = false; #if !defined(MOZ_WIDGET_ANDROID) if (args.length() >= 1) { if (!(args[0].isNumber() || args[0].isBoolean())) {