Bug 959787 - Handlify arguments for Call APIs r=terrence r=bz

This commit is contained in:
Jon Coppeard 2014-02-13 15:33:04 +00:00
parent f188ffbe5e
commit 8136579d75
36 changed files with 139 additions and 159 deletions

View File

@ -1042,8 +1042,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
return NS_ERROR_UNEXPECTED;
}
if (!JS_CallFunctionValue(cx, thisObject,
funval, argv, rval.address())) {
if (!JS_CallFunctionValue(cx, thisObject, funval, argv, &rval)) {
nsJSUtils::ReportPendingException(cx);
continue;
}
@ -1430,8 +1429,7 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL,
}
JS::Rooted<JS::Value> rval(cx);
JS::Rooted<JS::Value> methodVal(cx, JS::ObjectValue(*method));
ok = JS_CallFunctionValue(cx, global, methodVal,
JS::EmptyValueArray, rval.address());
ok = JS_CallFunctionValue(cx, global, methodVal, JS::EmptyValueArray, &rval);
} else if (script) {
ok = JS_ExecuteScript(cx, global, script, nullptr);
}

View File

@ -2060,7 +2060,7 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
}
JS::Rooted<JS::Value> frval(cx);
bool ret = JS_CallFunctionValue(cx, thisObject, funval, argv, frval.address());
bool ret = JS_CallFunctionValue(cx, thisObject, funval, argv, &frval);
if (!ret) {
return NS_ERROR_FAILURE;

View File

@ -1608,8 +1608,7 @@ NativeToString(JSContext* cx, JS::Handle<JSObject*> wrapper,
}
MOZ_ASSERT(JS_ObjectIsCallable(cx, &toString.toObject()));
JS::Rooted<JS::Value> toStringResult(cx);
if (JS_CallFunctionValue(cx, obj, toString, JS::EmptyValueArray,
toStringResult.address())) {
if (JS_CallFunctionValue(cx, obj, toString, JS::EmptyValueArray, &toStringResult)) {
str = toStringResult.toString();
} else {
str = nullptr;

View File

@ -11332,15 +11332,16 @@ class CallbackMethod(CallbackMember):
def getCall(self):
replacements = {
"errorReturn" : self.getDefaultRetval(),
"declThis": self.getThisDecl(),
"thisVal": self.getThisVal(),
"getCallable": self.getCallableDecl(),
"declCallable": self.getCallableDecl(),
"callGuard": self.getCallGuard()
}
if self.argCount > 0:
replacements["args"] = "JS::HandleValueArray::subarray(argv, 0, argc)"
else:
replacements["args"] = "JS::EmptyValueArray"
return string.Template("${getCallable}"
return string.Template("${declCallable}${declThis}"
"if (${callGuard}!JS::Call(cx, ${thisVal}, callable,\n"
" ${args}, &rval)) {\n"
" aRv.Throw(NS_ERROR_UNEXPECTED);\n"
@ -11353,6 +11354,9 @@ class CallCallback(CallbackMethod):
CallbackMethod.__init__(self, callback.signatures()[0], "Call",
descriptorProvider, needThisHandling=True)
def getThisDecl(self):
return ""
def getThisVal(self):
return "aThisVal"
@ -11376,13 +11380,18 @@ class CallbackOperationBase(CallbackMethod):
self.methodName = descriptor.binaryNames.get(jsName, jsName)
CallbackMethod.__init__(self, signature, nativeName, descriptor, singleOperation, rethrowContentException)
def getThisVal(self):
def getThisDecl(self):
if not self.singleOperation:
return "JS::ObjectValue(*mCallback)"
return "JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));\n"
# This relies on getCallableDecl declaring a boolean
# isCallable in the case when we're a single-operation
# interface.
return "isCallable ? aThisVal.get() : JS::ObjectValue(*mCallback)"
return (
'JS::Rooted<JS::Value> thisValue(cx, isCallable ? aThisVal.get()\n'
' : JS::ObjectValue(*mCallback));\n')
def getThisVal(self):
return "thisValue"
def getCallableDecl(self):
replacements = {

View File

@ -623,18 +623,19 @@ doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
nsCxPusher pusher;
pusher.Push(cx);
JSAutoCompartment ac(cx, npjsobj->mJSObj);
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, jsobj);
JS::Rooted<JS::Value> fv(cx);
AutoJSExceptionReporter reporter(cx);
if (method != NPIdentifier_VOID) {
if (!GetProperty(cx, npjsobj->mJSObj, method, &fv) ||
if (!GetProperty(cx, jsobj, method, &fv) ||
::JS_TypeOfValue(cx, fv) != JSTYPE_FUNCTION) {
return false;
}
} else {
fv = OBJECT_TO_JSVAL(npjsobj->mJSObj);
fv.setObject(*jsobj);
}
// Convert args
@ -652,14 +653,14 @@ doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
if (ctorCall) {
JSObject *newObj =
::JS_New(cx, npjsobj->mJSObj, jsargs.length(), jsargs.begin());
::JS_New(cx, jsobj, jsargs.length(), jsargs.begin());
if (newObj) {
v.setObject(*newObj);
ok = true;
}
} else {
ok = ::JS_CallFunctionValue(cx, npjsobj->mJSObj, fv, jsargs, v.address());
ok = ::JS_CallFunctionValue(cx, jsobj, fv, jsargs, &v);
}
if (ok)
@ -1605,7 +1606,7 @@ NPObjWrapper_Convert(JSContext *cx, JS::Handle<JSObject*> obj, JSType hint, JS::
if (!JS_GetProperty(cx, obj, "toString", &v))
return false;
if (!JSVAL_IS_PRIMITIVE(v) && JS_ObjectIsCallable(cx, JSVAL_TO_OBJECT(v))) {
if (!JS_CallFunctionValue(cx, obj, v, JS::EmptyValueArray, vp.address()))
if (!JS_CallFunctionValue(cx, obj, v, JS::EmptyValueArray, vp))
return false;
if (JSVAL_IS_PRIMITIVE(vp))
return true;

View File

@ -220,7 +220,7 @@ nsJSON::EncodeInternal(JSContext* cx, const JS::Value& aValue,
toJSON.isObject() &&
JS_ObjectIsCallable(cx, &toJSON.toObject())) {
// If toJSON is implemented, it must not throw
if (!JS_CallFunctionValue(cx, obj, toJSON, JS::EmptyValueArray, val.address())) {
if (!JS_CallFunctionValue(cx, obj, toJSON, JS::EmptyValueArray, &val)) {
if (JS_IsExceptionPending(cx))
// passing NS_OK will throw the pending exception
return NS_OK;

View File

@ -327,7 +327,7 @@ private:
args[2].set(stackValue);
JS::Rooted<JS::Value> ret(cx);
JS_CallFunctionName(cx, consoleObj, "queueCall", args, ret.address());
JS_CallFunctionName(cx, consoleObj, "queueCall", args, &ret);
}
WorkerConsole* mConsole;

View File

@ -5395,14 +5395,11 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
if (!info->mTimeoutCallable.isUndefined()) {
JS::Rooted<JS::Value> rval(aCx);
/*
* unsafeGet() is needed below because the argument is a not a const
* pointer, even though values are not modified.
*/
JS::HandleValueArray args =
JS::HandleValueArray::fromMarkedLocation(info->mExtraArgVals.Length(),
info->mExtraArgVals.Elements()->unsafeGet());
if (!JS_CallFunctionValue(aCx, global, info->mTimeoutCallable, args, rval.address()) &&
info->mExtraArgVals.Elements()->address());
JS::Rooted<JS::Value> callable(aCx, info->mTimeoutCallable);
if (!JS_CallFunctionValue(aCx, global, callable, args, &rval) &&
!JS_ReportPendingException(aCx)) {
retval = false;
break;

View File

@ -334,8 +334,8 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement)
bool ok = true;
if (scriptAllowed) {
JS::Rooted<JS::Value> retval(cx);
ok = ::JS_CallFunctionValue(cx, thisObject, OBJECT_TO_JSVAL(method),
JS::EmptyValueArray, retval.address());
JS::Rooted<JS::Value> methodVal(cx, JS::ObjectValue(*method));
ok = ::JS::Call(cx, thisObject, methodVal, JS::EmptyValueArray, &retval);
}
if (!ok) {

View File

@ -167,7 +167,7 @@ DispatchNFCEvent::RunTask(JSContext* aCx)
memcpy(JS_GetArrayBufferViewData(array), mMessage->mData, mMessage->mSize);
JS::Rooted<JS::Value> rval(aCx);
return JS_CallFunctionName(aCx, obj, "onNfcMessage", arrayVal, rval.address());
return JS_CallFunctionName(aCx, obj, "onNfcMessage", arrayVal, &rval);
}
class NfcConnector : public mozilla::ipc::UnixSocketConnector

View File

@ -174,7 +174,7 @@ DispatchRILEvent::RunTask(JSContext *aCx)
memcpy(JS_GetArrayBufferViewData(array), mMessage->mData, mMessage->mSize);
JS::Rooted<JS::Value> rval(aCx);
return JS_CallFunctionName(aCx, obj, "onRILMessage", arrayVal, rval.address());
return JS_CallFunctionName(aCx, obj, "onRILMessage", arrayVal, &rval);
}
class RilConnector : public mozilla::ipc::UnixSocketConnector

View File

@ -73,7 +73,8 @@ TestShellCommandParent::RunCallback(const nsString& aResponse)
JS::Rooted<JS::Value> strVal(mCx, JS::StringValue(str));
JS::Rooted<JS::Value> rval(mCx);
bool ok = JS_CallFunctionValue(mCx, global, mCallback, strVal, rval.address());
JS::Rooted<JS::Value> callback(mCx, mCallback);
bool ok = JS_CallFunctionValue(mCx, global, callback, strVal, &rval);
NS_ENSURE_TRUE(ok, false);
return true;

View File

@ -502,7 +502,7 @@ JavaScriptChild::AnswerCall(const ObjectId &objId, const nsTArray<JSParam> &argv
ContextOptionsRef(cx).setDontReportUncaught(true);
HandleValueArray args = HandleValueArray::subarray(vals, 2, vals.length() - 2);
bool success = JS::Call(cx, vals[1], vals[0], args, &rval);
bool success = JS::Call(cx, vals.handleAt(1), vals.handleAt(0), args, &rval);
if (!success)
return fail(cx, rs);
}

View File

@ -37,6 +37,8 @@ template <typename T> class AutoVectorRooter;
template<typename K, typename V> class AutoHashMapRooter;
template<typename T> class AutoHashSetRooter;
class HandleValueArray;
}
// Do the importing.
@ -121,6 +123,8 @@ using JS::MutableHandleValue;
using JS::NullHandleValue;
using JS::UndefinedHandleValue;
using JS::HandleValueArray;
using JS::Zone;
} /* namespace js */

View File

@ -6134,12 +6134,12 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData)
RootedObject typeObj(cx, cinfo->typeObj);
RootedObject thisObj(cx, cinfo->thisObj);
RootedObject jsfnObj(cx, cinfo->jsfnObj);
RootedValue jsfnVal(cx, ObjectValue(*cinfo->jsfnObj));
JS_AbortIfWrongThread(JS_GetRuntime(cx));
JSAutoRequest ar(cx);
JSAutoCompartment ac(cx, jsfnObj);
JSAutoCompartment ac(cx, cinfo->jsfnObj);
// Assert that our CIFs agree.
FunctionInfo* fninfo = FunctionType::GetFunctionInfo(typeObj);
@ -6187,7 +6187,7 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData)
// Call the JS function. 'thisObj' may be nullptr, in which case the JS
// engine will find an appropriate object to use.
RootedValue rval(cx);
bool success = JS_CallFunctionValue(cx, thisObj, OBJECT_TO_JSVAL(jsfnObj), argv, rval.address());
bool success = JS_CallFunctionValue(cx, thisObj, jsfnVal, argv, &rval);
// Convert the result. Note that we pass 'isArgument = false', such that
// ImplicitConvert will *not* autoconvert a JS string into a pointer-to-char

View File

@ -20,8 +20,8 @@ BEGIN_TEST(test_BindCallable)
CHECK(newCallable);
JS::RootedValue retval(cx);
bool called = JS_CallFunctionValue(cx, nullptr, OBJECT_TO_JSVAL(newCallable), JS::EmptyValueArray,
retval.address());
JS::RootedValue fun(cx, JS::ObjectValue(*newCallable));
bool called = JS_CallFunctionValue(cx, JS::NullPtr(), fun, JS::EmptyValueArray, &retval);
CHECK(called);
CHECK(JSVAL_IS_INT(retval));

View File

@ -51,11 +51,12 @@ BEGIN_TEST(test_CallNonGenericMethodOnProxy)
CHECK(customA);
JS_SetReservedSlot(customA, CUSTOM_SLOT, Int32Value(17));
JSFunction *customMethodA = JS_NewFunction(cx, CustomMethod, 0, 0, customA, "customMethodA");
JS::RootedFunction customMethodA(cx, JS_NewFunction(cx, CustomMethod, 0, 0,
customA, "customMethodA"));
CHECK(customMethodA);
JS::RootedValue rval(cx);
CHECK(JS_CallFunction(cx, customA, customMethodA, JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunction(cx, customA, customMethodA, JS::EmptyValueArray, &rval));
CHECK_SAME(rval, Int32Value(17));
// Now create the second global object and compartment...
@ -73,14 +74,14 @@ BEGIN_TEST(test_CallNonGenericMethodOnProxy)
CHECK(customMethodB);
JS::RootedValue rval(cx);
CHECK(JS_CallFunction(cx, customB, customMethodB, JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunction(cx, customB, customMethodB, JS::EmptyValueArray, &rval));
CHECK_SAME(rval, Int32Value(42));
JS::RootedObject wrappedCustomA(cx, customA);
CHECK(JS_WrapObject(cx, &wrappedCustomA));
JS::RootedValue rval2(cx);
CHECK(JS_CallFunction(cx, wrappedCustomA, customMethodB, JS::EmptyValueArray, rval2.address()));
CHECK(JS_CallFunction(cx, wrappedCustomA, customMethodB, JS::EmptyValueArray, &rval2));
CHECK_SAME(rval, Int32Value(42));
}

View File

@ -26,14 +26,16 @@ static JSObject *trusted_fun = nullptr;
static bool
CallTrusted(JSContext *cx, unsigned argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (!JS_SaveFrameChain(cx))
return false;
bool ok = false;
{
JSAutoCompartment ac(cx, trusted_glob);
ok = JS_CallFunctionValue(cx, nullptr, JS::ObjectValue(*trusted_fun),
JS::EmptyValueArray, vp);
JS::RootedValue funVal(cx, JS::ObjectValue(*trusted_fun));
ok = JS_CallFunctionValue(cx, JS::NullPtr(), funVal, JS::EmptyValueArray, args.rval());
}
JS_RestoreFrameChain(cx);
return ok;
@ -49,7 +51,7 @@ BEGIN_TEST(testChromeBuffer)
if (!JS_AddNamedObjectRoot(cx, &trusted_glob, "trusted-global"))
return false;
JSFunction *fun;
JS::RootedFunction fun(cx);
/*
* Check that, even after untrusted content has exhausted the stack, code
@ -91,7 +93,7 @@ BEGIN_TEST(testChromeBuffer)
bytes, strlen(bytes), options));
JS::RootedValue rval(cx);
CHECK(JS_CallFunction(cx, nullptr, fun, v, rval.address()));
CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, v, &rval));
CHECK(JSVAL_TO_INT(rval) == 100);
}
@ -132,7 +134,7 @@ BEGIN_TEST(testChromeBuffer)
bytes, strlen(bytes), options));
JS::RootedValue rval(cx);
CHECK(JS_CallFunction(cx, nullptr, fun, v, rval.address()));
CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, v, &rval));
bool match;
CHECK(JS_StringEqualsAscii(cx, JSVAL_TO_STRING(rval), "From trusted: InternalError: too much recursion", &match));
CHECK(match);
@ -171,7 +173,7 @@ BEGIN_TEST(testChromeBuffer)
JS::RootedValue arg(cx, JS::ObjectValue(*callTrusted));
JS::RootedValue rval(cx);
CHECK(JS_CallFunction(cx, nullptr, fun, arg, rval.address()));
CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, arg, &rval));
CHECK(JSVAL_TO_INT(rval) == 42);
}

View File

@ -63,7 +63,7 @@ BEGIN_TEST(testClassGetter_isCalled)
for (int i = 1; i < 9; i++) {
JS::RootedValue rval(cx);
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, &rval));
CHECK_SAME(INT_TO_JSVAL(called_test_fn), INT_TO_JSVAL(i));
CHECK_SAME(INT_TO_JSVAL(called_test_prop_get), INT_TO_JSVAL(4 * i));
}

View File

@ -138,7 +138,7 @@ BEGIN_TEST(test_cloneScriptWithPrincipals)
JS::RootedValue v(cx);
JS::RootedValue arg(cx, JS::Int32Value(1));
CHECK(JS_CallFunctionValue(cx, B, JS::ObjectValue(*cloned), arg, v.address()));
CHECK(JS_CallFunctionValue(cx, B, clonedValue, arg, &v));
CHECK(v.isObject());
JSObject *funobj = &v.toObject();

View File

@ -226,7 +226,7 @@ bool testIndirectEval(JS::HandleObject scope, const char *code)
CHECK(codestr);
JS::RootedValue arg(cx, JS::StringValue(codestr));
JS::RootedValue v(cx);
CHECK(JS_CallFunctionName(cx, scope, "eval", arg, v.address()));
CHECK(JS_CallFunctionName(cx, scope, "eval", arg, &v));
}
JS::RootedValue hitsv(cx);

View File

@ -20,7 +20,7 @@ BEGIN_TEST(testErrorCopying_columnCopied)
JS::RootedValue rval(cx);
JS_SetErrorReporter(cx, my_ErrorReporter);
CHECK(!JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, rval.address()));
CHECK(!JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, &rval));
CHECK(column == 27);
return true;
}

View File

@ -15,7 +15,7 @@ BEGIN_TEST(testException_bug860435)
CHECK(fun.isObject());
JS::RootedValue v(cx);
JS_CallFunctionValue(cx, global, fun, JS::EmptyValueArray, v.address());
JS_CallFunctionValue(cx, global, fun, JS::EmptyValueArray, &v);
CHECK(v.isObject());
JS::RootedObject obj(cx, &v.toObject());

View File

@ -55,7 +55,7 @@ BEGIN_TEST(testOps_bug559006)
for (int i = 0; i < 9; i++) {
JS::RootedValue rval(cx);
CHECK(JS_CallFunctionName(cx, global, "main", JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunctionName(cx, global, "main", JS::EmptyValueArray, &rval));
CHECK_SAME(rval, INT_TO_JSVAL(123));
}
return true;

View File

@ -42,7 +42,7 @@ test_fn2(JSContext *cx, unsigned argc, jsval *vp)
{
JS::RootedValue r(cx);
JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
return JS_CallFunctionName(cx, global, "d", JS::EmptyValueArray, r.address());
return JS_CallFunctionName(cx, global, "d", JS::EmptyValueArray, &r);
}
static bool
@ -104,13 +104,13 @@ BEGIN_TEST(testProfileStrings_isCalledWithInterpreter)
{
JS::RootedValue rval(cx);
/* Make sure the stack resets and we have an entry for each stack */
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, &rval));
CHECK(psize == 0);
CHECK(max_stack >= 8);
CHECK(cx->runtime()->spsProfiler.stringsCount() == 8);
/* Make sure the stack resets and we added no new entries */
max_stack = 0;
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, &rval));
CHECK(psize == 0);
CHECK(max_stack >= 8);
CHECK(cx->runtime()->spsProfiler.stringsCount() == 8);
@ -118,7 +118,7 @@ BEGIN_TEST(testProfileStrings_isCalledWithInterpreter)
reset(cx);
{
JS::RootedValue rval(cx);
CHECK(JS_CallFunctionName(cx, global, "check2", JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunctionName(cx, global, "check2", JS::EmptyValueArray, &rval));
CHECK(cx->runtime()->spsProfiler.stringsCount() == 5);
CHECK(max_stack >= 6);
CHECK(psize == 0);
@ -129,7 +129,7 @@ BEGIN_TEST(testProfileStrings_isCalledWithInterpreter)
{
JS::RootedValue rval(cx);
pstack[3].setLabel((char*) 1234);
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, &rval));
CHECK((size_t) pstack[3].label() == 1234);
CHECK(max_stack >= 8);
CHECK(psize == 0);
@ -158,14 +158,14 @@ BEGIN_TEST(testProfileStrings_isCalledWithJIT)
{
JS::RootedValue rval(cx);
/* Make sure the stack resets and we have an entry for each stack */
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, &rval));
CHECK(psize == 0);
CHECK(max_stack >= 8);
/* Make sure the stack resets and we added no new entries */
uint32_t cnt = cx->runtime()->spsProfiler.stringsCount();
max_stack = 0;
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, &rval));
CHECK(psize == 0);
CHECK(cx->runtime()->spsProfiler.stringsCount() == cnt);
CHECK(max_stack >= 8);
@ -178,7 +178,7 @@ BEGIN_TEST(testProfileStrings_isCalledWithJIT)
/* Limit the size of the stack and make sure we don't overflow */
JS::RootedValue rval(cx);
pstack[3].setLabel((char*) 1234);
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, rval.address()));
CHECK(JS_CallFunctionName(cx, global, "check", JS::EmptyValueArray, &rval));
CHECK(psize == 0);
CHECK(max_stack >= 8);
CHECK((size_t) pstack[3].label() == 1234);
@ -200,7 +200,7 @@ BEGIN_TEST(testProfileStrings_isCalledWhenError)
{
JS::RootedValue rval(cx);
/* Make sure the stack resets and we have an entry for each stack */
bool ok = JS_CallFunctionName(cx, global, "check2", JS::EmptyValueArray, rval.address());
bool ok = JS_CallFunctionName(cx, global, "check2", JS::EmptyValueArray, &rval);
CHECK(!ok);
CHECK(psize == 0);
CHECK(cx->runtime()->spsProfiler.stringsCount() == 1);
@ -224,7 +224,7 @@ BEGIN_TEST(testProfileStrings_worksWhenEnabledOnTheFly)
{
/* enable it in the middle of JS and make sure things check out */
JS::RootedValue rval(cx);
JS_CallFunctionName(cx, global, "a", JS::EmptyValueArray, rval.address());
JS_CallFunctionName(cx, global, "a", JS::EmptyValueArray, &rval);
CHECK(psize == 0);
CHECK(max_stack >= 1);
CHECK(cx->runtime()->spsProfiler.stringsCount() == 1);
@ -236,7 +236,7 @@ BEGIN_TEST(testProfileStrings_worksWhenEnabledOnTheFly)
{
/* now disable in the middle of js */
JS::RootedValue rval(cx);
JS_CallFunctionName(cx, global, "c", JS::EmptyValueArray, rval.address());
JS_CallFunctionName(cx, global, "c", JS::EmptyValueArray, &rval);
CHECK(psize == 0);
}
@ -245,7 +245,7 @@ BEGIN_TEST(testProfileStrings_worksWhenEnabledOnTheFly)
{
/* now disable in the middle of js, but re-enable before final exit */
JS::RootedValue rval(cx);
JS_CallFunctionName(cx, global, "e", JS::EmptyValueArray, rval.address());
JS_CallFunctionName(cx, global, "e", JS::EmptyValueArray, &rval);
CHECK(psize == 0);
CHECK(max_stack >= 3);
}
@ -259,7 +259,7 @@ BEGIN_TEST(testProfileStrings_worksWhenEnabledOnTheFly)
JS::RootedValue rval(cx);
/* disable, and make sure that if we try to re-enter the JIT the pop
* will still happen */
JS_CallFunctionName(cx, global, "f", JS::EmptyValueArray, rval.address());
JS_CallFunctionName(cx, global, "f", JS::EmptyValueArray, &rval);
CHECK(psize == 0);
}
return true;

View File

@ -4965,28 +4965,22 @@ JS_EvaluateScript(JSContext *cx, JSObject *objArg, const char *bytes, unsigned n
}
JS_PUBLIC_API(bool)
JS_CallFunction(JSContext *cx, JSObject *objArg, JSFunction *fun, const JS::HandleValueArray& args,
jsval *rval)
JS_CallFunction(JSContext *cx, HandleObject obj, HandleFunction fun, const HandleValueArray& args,
MutableHandleValue rval)
{
RootedObject obj(cx, objArg);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, fun, args);
AutoLastFrameCheck lfc(cx);
RootedValue rv(cx);
if (!Invoke(cx, ObjectOrNullValue(obj), ObjectValue(*fun), args.length(), args.begin(), &rv))
return false;
*rval = rv;
return true;
return Invoke(cx, ObjectOrNullValue(obj), ObjectValue(*fun), args.length(), args.begin(), rval);
}
JS_PUBLIC_API(bool)
JS_CallFunctionName(JSContext *cx, JSObject *objArg, const char *name,
const JS::HandleValueArray& args, jsval *rval)
JS_CallFunctionName(JSContext *cx, HandleObject obj, const char *name, const HandleValueArray& args,
MutableHandleValue rval)
{
RootedObject obj(cx, objArg);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -5002,33 +4996,24 @@ JS_CallFunctionName(JSContext *cx, JSObject *objArg, const char *name,
if (!JSObject::getGeneric(cx, obj, obj, id, &v))
return false;
RootedValue rv(cx);
if (!Invoke(cx, ObjectOrNullValue(obj), v, args.length(), args.begin(), &rv))
return false;
*rval = rv;
return true;
return Invoke(cx, ObjectOrNullValue(obj), v, args.length(), args.begin(), rval);
}
JS_PUBLIC_API(bool)
JS_CallFunctionValue(JSContext *cx, JSObject *objArg, jsval fval, const JS::HandleValueArray& args,
jsval *rval)
JS_CallFunctionValue(JSContext *cx, HandleObject obj, HandleValue fval, const HandleValueArray& args,
MutableHandleValue rval)
{
RootedObject obj(cx, objArg);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, fval, args);
AutoLastFrameCheck lfc(cx);
RootedValue rv(cx);
if (!Invoke(cx, ObjectOrNullValue(obj), fval, args.length(), args.begin(), &rv))
return false;
*rval = rv;
return true;
return Invoke(cx, ObjectOrNullValue(obj), fval, args.length(), args.begin(), rval);
}
JS_PUBLIC_API(bool)
JS::Call(JSContext *cx, jsval thisv, jsval fval, const JS::HandleValueArray& args,
JS::Call(JSContext *cx, HandleValue thisv, HandleValue fval, const JS::HandleValueArray& args,
MutableHandleValue rval)
{
AssertHeapIsIdle(cx);

View File

@ -3916,49 +3916,51 @@ Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &opti
} /* namespace JS */
extern JS_PUBLIC_API(bool)
JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, const JS::HandleValueArray& args,
jsval *rval);
JS_CallFunction(JSContext *cx, JS::HandleObject obj, JS::HandleFunction fun,
const JS::HandleValueArray& args, JS::MutableHandleValue rval);
extern JS_PUBLIC_API(bool)
JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, const JS::HandleValueArray& args,
jsval *rval);
JS_CallFunctionName(JSContext *cx, JS::HandleObject obj, const char *name,
const JS::HandleValueArray& args, JS::MutableHandleValue rval);
extern JS_PUBLIC_API(bool)
JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, const JS::HandleValueArray& args,
jsval *rval);
JS_CallFunctionValue(JSContext *cx, JS::HandleObject obj, JS::HandleValue fval,
const JS::HandleValueArray& args, JS::MutableHandleValue rval);
namespace JS {
static inline bool
Call(JSContext *cx, JSObject *thisObj, JSFunction *fun, const JS::HandleValueArray &args,
MutableHandleValue rval)
Call(JSContext *cx, JS::HandleObject thisObj, JS::HandleFunction fun,
const JS::HandleValueArray &args, MutableHandleValue rval)
{
return !!JS_CallFunction(cx, thisObj, fun, args, rval.address());
return !!JS_CallFunction(cx, thisObj, fun, args, rval);
}
static inline bool
Call(JSContext *cx, JSObject *thisObj, const char *name, const JS::HandleValueArray& args,
Call(JSContext *cx, JS::HandleObject thisObj, const char *name, const JS::HandleValueArray& args,
MutableHandleValue rval)
{
return !!JS_CallFunctionName(cx, thisObj, name, args, rval.address());
return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
}
static inline bool
Call(JSContext *cx, JSObject *thisObj, jsval fun, const JS::HandleValueArray& args,
Call(JSContext *cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args,
MutableHandleValue rval)
{
return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval.address());
return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
}
extern JS_PUBLIC_API(bool)
Call(JSContext *cx, jsval thisv, jsval fun, const JS::HandleValueArray& args,
Call(JSContext *cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args,
MutableHandleValue rval);
static inline bool
Call(JSContext *cx, jsval thisv, JSObject *funObj, const JS::HandleValueArray& args,
Call(JSContext *cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args,
MutableHandleValue rval)
{
return Call(cx, thisv, OBJECT_TO_JSVAL(funObj), args, rval);
JS_ASSERT(funObj);
JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
return Call(cx, thisv, fun, args, rval);
}
} /* namespace JS */

View File

@ -322,11 +322,12 @@ ShellOperationCallback(JSContext *cx)
bool result;
if (!gTimeoutFunc.isNull()) {
JSAutoCompartment ac(cx, &gTimeoutFunc.toObject());
RootedValue returnedValue(cx);
if (!JS_CallFunctionValue(cx, nullptr, gTimeoutFunc, JS::EmptyValueArray, returnedValue.address()))
RootedValue rval(cx);
HandleValue timeoutFunc = HandleValue::fromMarkedLocation(&gTimeoutFunc);
if (!JS_CallFunctionValue(cx, JS::NullPtr(), timeoutFunc, JS::EmptyValueArray, &rval))
return false;
if (returnedValue.isBoolean())
result = returnedValue.toBoolean();
if (rval.isBoolean())
result = rval.toBoolean();
else
result = false;
} else {
@ -3911,40 +3912,20 @@ GetSelfHostedValue(JSContext *cx, unsigned argc, jsval *vp)
}
class ShellSourceHook: public SourceHook {
// The runtime to which we attached a source hook.
JSRuntime *rt;
// The function we should call to lazily retrieve source code.
// The constructor and destructor take care of rooting this with the
// runtime.
JSObject *fun;
PersistentRootedFunction fun;
public:
ShellSourceHook() : rt(nullptr), fun(nullptr) { }
bool init(JSContext *cx, JSFunction &fun) {
JS_ASSERT(!this->rt);
JS_ASSERT(!this->fun);
this->rt = cx->runtime();
this->fun = &fun;
return JS_AddNamedObjectRoot(cx, &this->fun,
"lazy source callback, set with withSourceHook");
}
~ShellSourceHook() {
if (fun)
JS_RemoveObjectRootRT(rt, &fun);
}
ShellSourceHook(JSContext *cx, JSFunction &fun) : fun(cx, &fun) {}
bool load(JSContext *cx, const char *filename, jschar **src, size_t *length) {
JS_ASSERT(fun);
RootedString str(cx, JS_NewStringCopyZ(cx, filename));
if (!str)
return false;
RootedValue filenameValue(cx, StringValue(str));
RootedValue result(cx);
if (!Call(cx, UndefinedValue(), &fun->as<JSFunction>(), filenameValue, &result))
if (!Call(cx, UndefinedHandleValue, fun, filenameValue, &result))
return false;
str = JS::ToString(cx, result);
@ -3982,15 +3963,14 @@ WithSourceHook(JSContext *cx, unsigned argc, jsval *vp)
return false;
}
ShellSourceHook *hook = new ShellSourceHook();
if (!hook->init(cx, args[0].toObject().as<JSFunction>())) {
delete hook;
ShellSourceHook *hook = new ShellSourceHook(cx, args[0].toObject().as<JSFunction>());
if (!hook)
return false;
}
SourceHook *savedHook = js::ForgetSourceHook(cx->runtime());
js::SetSourceHook(cx->runtime(), hook);
bool result = Call(cx, UndefinedValue(), &args[1].toObject(), JS::EmptyValueArray, args.rval());
RootedObject fun(cx, &args[1].toObject());
bool result = Call(cx, UndefinedHandleValue, fun, JS::EmptyValueArray, args.rval());
js::SetSourceHook(cx->runtime(), savedHook);
return result;
}

View File

@ -1013,7 +1013,7 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
ok = JS_ExecuteScriptVersion(cx, obj, script, nullptr, JSVERSION_LATEST);
} else {
RootedValue rval(cx);
ok = JS_CallFunction(cx, obj, function, JS::EmptyValueArray, rval.address());
ok = JS_CallFunction(cx, obj, function, JS::EmptyValueArray, &rval);
}
}

View File

@ -349,7 +349,7 @@ mozJSSubScriptLoader::DoLoadSubScriptWithOptions(const nsAString &url,
bool ok = false;
if (function) {
ok = JS_CallFunction(cx, targetObj, function, JS::EmptyValueArray, retval.address());
ok = JS_CallFunction(cx, targetObj, function, JS::EmptyValueArray, retval);
} else {
ok = JS_ExecuteScriptVersion(cx, targetObj, script, retval.address(), version);
}

View File

@ -760,13 +760,14 @@ xpc::SandboxCallableProxyHandler::call(JSContext *cx, JS::Handle<JSObject*> prox
// methods are always non-strict, we can just assume non-strict semantics
// if the sandboxPrototype is an Xray Wrapper, which lets us appropriately
// remap |this|.
JS::Value thisVal =
WrapperFactory::IsXrayWrapper(sandboxProxy) ? args.computeThis(cx) : args.thisv();
bool isXray = WrapperFactory::IsXrayWrapper(sandboxProxy);
RootedValue thisVal(cx, isXray ? args.computeThis(cx) : args.thisv());
if (thisVal == ObjectValue(*sandboxGlobal)) {
thisVal = ObjectValue(*js::GetProxyTargetObject(sandboxProxy));
}
return JS::Call(cx, thisVal, js::GetProxyPrivate(proxy), args, args.rval());
RootedValue func(cx, js::GetProxyPrivate(proxy));
return JS::Call(cx, thisVal, func, args, args.rval());
}
xpc::SandboxCallableProxyHandler xpc::sandboxCallableProxyHandler;
@ -1743,11 +1744,11 @@ NonCloningFunctionForwarder(JSContext *cx, unsigned argc, Value *vp)
RootedValue v(cx, js::GetFunctionNativeReserved(&args.callee(), 0));
MOZ_ASSERT(v.isObject(), "weird function");
JSObject *obj = JS_THIS_OBJECT(cx, vp);
RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));
if (!obj) {
return false;
}
return JS_CallFunctionValue(cx, obj, v, args, vp);
return JS_CallFunctionValue(cx, obj, v, args, args.rval());
}
/*
@ -1774,10 +1775,9 @@ CloningFunctionForwarder(JSContext *cx, unsigned argc, Value *vp)
// JS API does not support any JSObject to JSFunction conversion,
// so let's use JS_CallFunctionValue instead.
RootedValue functionVal(cx);
functionVal.setObject(*origFunObj);
RootedValue functionVal(cx, ObjectValue(*origFunObj));
if (!JS_CallFunctionValue(cx, nullptr, functionVal, args, args.rval().address()))
if (!JS_CallFunctionValue(cx, JS::NullPtr(), functionVal, args, args.rval()))
return false;
}

View File

@ -2157,7 +2157,7 @@ nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,JSContext *
JS::Rooted<JS::Value> arg(cx, ObjectValue(*iidObj));
RootedValue rval(cx);
if (!JS_CallFunctionName(cx, cidObj, "createInstance", arg, rval.address()) ||
if (!JS_CallFunctionName(cx, cidObj, "createInstance", arg, &rval) ||
rval.isPrimitive()) {
// createInstance will have thrown an exception
*_retval = false;
@ -2177,7 +2177,7 @@ nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,JSContext *
}
RootedValue dummy(cx);
if (!JS_CallFunctionValue(cx, newObj, fun, args, dummy.address())) {
if (!JS_CallFunctionValue(cx, newObj, fun, args, &dummy)) {
// function should have thrown an exception
*_retval = false;
return NS_OK;
@ -3382,7 +3382,7 @@ nsXPCComponents_Utils::GetIncumbentGlobal(HandleValue aCallback,
// Invoke the callback, if passed.
if (aCallback.isObject()) {
RootedValue ignored(aCx);
if (!JS_CallFunctionValue(aCx, nullptr, aCallback, globalVal, ignored.address()))
if (!JS_CallFunctionValue(aCx, JS::NullPtr(), aCallback, globalVal, &ignored))
return NS_ERROR_FAILURE;
}

View File

@ -664,8 +664,9 @@ XPCShellOperationCallback(JSContext *cx)
JSAutoCompartment ac(cx, &sScriptedOperationCallback.toObject());
RootedValue rv(cx);
if (!JS_CallFunctionValue(cx, nullptr, sScriptedOperationCallback,
JS::EmptyValueArray, rv.address()) || !rv.isBoolean())
RootedValue callback(cx, sScriptedOperationCallback);
if (!JS_CallFunctionValue(cx, JS::NullPtr(), callback, JS::EmptyValueArray, &rv) ||
!rv.isBoolean())
{
NS_WARNING("Scripted operation callback failed! Terminating script.");
JS_ClearPendingException(cx);

View File

@ -232,7 +232,7 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
AutoSaveContextOptions asco(cx);
ContextOptionsRef(cx).setDontReportUncaught(true);
RootedValue arg(cx, JS::ObjectValue(*id));
success = JS_CallFunctionValue(cx, jsobj, fun, arg, retval.address());
success = JS_CallFunctionValue(cx, jsobj, fun, arg, &retval);
}
if (!success && JS_IsExceptionPending(cx)) {
@ -1282,7 +1282,7 @@ pre_call_clean_up:
AutoSaveContextOptions asco(cx);
ContextOptionsRef(cx).setDontReportUncaught(true);
success = JS_CallFunctionValue(cx, thisObj, fval, args, rval.address());
success = JS_CallFunctionValue(cx, thisObj, fval, args, &rval);
} else {
// The property was not an object so can't be a function.
// Let's build and 'throw' an exception.

View File

@ -690,8 +690,8 @@ ProxyAutoConfig::GetProxyForURI(const nsCString &aTestURI,
args[1].setString(hostString);
JS::Rooted<JS::Value> rval(cx);
bool ok = JS_CallFunctionName(cx, mJSRuntime->Global(),
"FindProxyForURL", args, rval.address());
JS::Rooted<JSObject*> global(cx, mJSRuntime->Global());
bool ok = JS_CallFunctionName(cx, global, "FindProxyForURL", args, &rval);
if (ok && rval.isString()) {
nsDependentJSString pacString;

View File

@ -178,7 +178,7 @@ nsHTTPIndex::OnFTPControlLog(bool server, const char *msg)
global,
"OnFTPControlLog",
params,
val.address());
&val);
return NS_OK;
}