Bug 1331662 part 2 - Replace nsJSUtils::EvaluateString calls by ExecutionContext scopes. r=bz

This commit is contained in:
Nicolas B. Pierron
2017-03-22 13:42:27 +00:00
parent 40c712fd15
commit fc0b4d8b45
10 changed files with 59 additions and 168 deletions

View File

@@ -13077,9 +13077,14 @@ nsGlobalWindow::RunTimeoutHandler(Timeout* aTimeout,
AutoEntryScript aes(this, reason, true);
JS::CompileOptions options(aes.cx());
options.setFileAndLine(filename, lineNo).setVersion(JSVERSION_DEFAULT);
options.setNoScriptRval(true);
JS::Rooted<JSObject*> global(aes.cx(), FastGetGlobalJSObject());
nsresult rv =
nsJSUtils::EvaluateString(aes.cx(), script, global, options);
nsresult rv = NS_OK;
{
nsJSUtils::ExecutionContext exec(aes.cx(), global);
rv = exec.CompileAndExec(options, script);
}
if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE) {
abortIntervalHandler = true;
}

View File

@@ -281,93 +281,6 @@ nsJSUtils::ExecutionContext::ExtractReturnValue(JS::MutableHandle<JS::Value> aRe
return NS_OK;
}
nsresult
nsJSUtils::EvaluateString(JSContext* aCx,
const nsAString& aScript,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions& aCompileOptions,
const EvaluateOptions& aEvaluateOptions,
JS::MutableHandle<JS::Value> aRetValue)
{
const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
JS::SourceBufferHolder::NoOwnership);
return EvaluateString(aCx, srcBuf, aEvaluationGlobal, aCompileOptions,
aEvaluateOptions, aRetValue, nullptr);
}
nsresult
nsJSUtils::EvaluateString(JSContext* aCx,
JS::SourceBufferHolder& aSrcBuf,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions& aCompileOptions,
const EvaluateOptions& aEvaluateOptions,
JS::MutableHandle<JS::Value> aRetValue,
void **aOffThreadToken)
{
ExecutionContext exec(aCx, aEvaluationGlobal);
exec.SetReturnValue(aCompileOptions)
.SetCoerceToString(aEvaluateOptions.coerceToString);
exec.SetScopeChain(aEvaluateOptions.scopeChain);
nsresult rv = NS_OK;
if (aOffThreadToken) {
JS::Rooted<JSScript*> script(aCx);
rv = exec.SyncAndExec(aOffThreadToken, &script);
} else {
rv = exec.CompileAndExec(aCompileOptions, aSrcBuf);
}
if (NS_FAILED(rv)) {
return rv;
}
if (!aCompileOptions.noScriptRval) {
return exec.ExtractReturnValue(aRetValue);
}
return rv;
}
nsresult
nsJSUtils::EvaluateString(JSContext* aCx,
JS::SourceBufferHolder& aSrcBuf,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions& aCompileOptions,
const EvaluateOptions& aEvaluateOptions,
JS::MutableHandle<JS::Value> aRetValue)
{
return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
aEvaluateOptions, aRetValue, nullptr);
}
nsresult
nsJSUtils::EvaluateString(JSContext* aCx,
const nsAString& aScript,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions& aCompileOptions)
{
EvaluateOptions options(aCx);
aCompileOptions.setNoScriptRval(true);
JS::RootedValue unused(aCx);
return EvaluateString(aCx, aScript, aEvaluationGlobal, aCompileOptions,
options, &unused);
}
nsresult
nsJSUtils::EvaluateString(JSContext* aCx,
JS::SourceBufferHolder& aSrcBuf,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions& aCompileOptions,
void **aOffThreadToken)
{
EvaluateOptions options(aCx);
aCompileOptions.setNoScriptRval(true);
JS::RootedValue unused(aCx);
return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
options, &unused, aOffThreadToken);
}
nsresult
nsJSUtils::CompileModule(JSContext* aCx,
JS::SourceBufferHolder& aSrcBuf,

View File

@@ -154,52 +154,6 @@ public:
const nsAString& aScript);
};
struct MOZ_STACK_CLASS EvaluateOptions {
bool coerceToString;
JS::AutoObjectVector scopeChain;
explicit EvaluateOptions(JSContext* cx)
: coerceToString(false)
, scopeChain(cx)
{}
EvaluateOptions& setCoerceToString(bool aCoerce) {
coerceToString = aCoerce;
return *this;
}
};
// aEvaluationGlobal is the global to evaluate in. The return value
// will then be wrapped back into the compartment aCx is in when
// this function is called. For all the EvaluateString overloads,
// the JSContext must come from an AutoJSAPI that has had
// TakeOwnershipOfErrorReporting() called on it.
static nsresult EvaluateString(JSContext* aCx,
const nsAString& aScript,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions &aCompileOptions,
const EvaluateOptions& aEvaluateOptions,
JS::MutableHandle<JS::Value> aRetValue);
static nsresult EvaluateString(JSContext* aCx,
JS::SourceBufferHolder& aSrcBuf,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions &aCompileOptions,
const EvaluateOptions& aEvaluateOptions,
JS::MutableHandle<JS::Value> aRetValue);
static nsresult EvaluateString(JSContext* aCx,
const nsAString& aScript,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions &aCompileOptions);
static nsresult EvaluateString(JSContext* aCx,
JS::SourceBufferHolder& aSrcBuf,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions &aCompileOptions,
void **aOffThreadToken);
static nsresult CompileModule(JSContext* aCx,
JS::SourceBufferHolder& aSrcBuf,
JS::Handle<JSObject*> aEvaluationGlobal,
@@ -219,16 +173,6 @@ public:
JS::AutoObjectVector& aScopeChain);
static void ResetTimeZone();
private:
// Implementation for our EvaluateString bits
static nsresult EvaluateString(JSContext* aCx,
JS::SourceBufferHolder& aSrcBuf,
JS::Handle<JSObject*> aEvaluationGlobal,
JS::CompileOptions& aCompileOptions,
const EvaluateOptions& aEvaluateOptions,
JS::MutableHandle<JS::Value> aRetValue,
void **aOffThreadToken);
};
template<typename T>

View File

@@ -2152,8 +2152,6 @@ nsScriptLoader::FillCompileOptionsForRequest(const AutoJSAPI&jsapi,
aOptions->setFileAndLine(aRequest->mURL.get(), aRequest->mLineNo);
aOptions->setVersion(JSVersion(aRequest->mJSVersion));
aOptions->setIsRunOnce(true);
// We only need the setNoScriptRval bit when compiling off-thread here, since
// otherwise nsJSUtils::EvaluateString will set it up for us.
aOptions->setNoScriptRval(true);
if (aRequest->mHasSourceMapURL) {
aOptions->setSourceMapURL(aRequest->mSourceMapURL.get());
@@ -2258,10 +2256,17 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest)
rv = FillCompileOptionsForRequest(aes, aRequest, global, &options);
if (NS_SUCCEEDED(rv)) {
nsAutoString inlineData;
SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
rv = nsJSUtils::EvaluateString(aes.cx(), srcBuf, global, options,
aRequest->OffThreadTokenPtr());
{
nsJSUtils::ExecutionContext exec(aes.cx(), global);
if (aRequest->mOffThreadToken) {
JS::Rooted<JSScript*> script(aes.cx());
rv = exec.SyncAndExec(&aRequest->mOffThreadToken, &script);
} else {
nsAutoString inlineData;
SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
rv = exec.CompileAndExec(options, srcBuf);
}
}
}
}
}

View File

@@ -269,10 +269,14 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
JS::CompileOptions options(cx);
options.setFileAndLine(mURL.get(), 1)
.setVersion(JSVERSION_DEFAULT);
nsJSUtils::EvaluateOptions evalOptions(cx);
evalOptions.setCoerceToString(true);
rv = nsJSUtils::EvaluateString(cx, NS_ConvertUTF8toUTF16(script),
globalJSObject, options, evalOptions, &v);
{
nsJSUtils::ExecutionContext exec(cx, globalJSObject);
exec.SetCoerceToString(true);
exec.CompileAndExec(options, NS_ConvertUTF8toUTF16(script));
rv = exec.ExtractReturnValue(&v);
}
js::AssertSameCompartment(cx, v);
if (NS_FAILED(rv) || !(v.isString() || v.isUndefined())) {
return NS_ERROR_MALFORMED_URI;

View File

@@ -1368,14 +1368,23 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
options.setFileAndLine(spec, 0)
.setVersion(JSVERSION_DEFAULT);
JS::Rooted<JS::Value> rval(cx);
nsJSUtils::EvaluateOptions evalOptions(cx);
JS::AutoObjectVector scopeChain(cx);
if (obj != js::GetGlobalForObjectCrossCompartment(obj) &&
!evalOptions.scopeChain.append(obj)) {
!scopeChain.append(obj)) {
return false;
}
obj = js::GetGlobalForObjectCrossCompartment(obj);
nsresult rv = nsJSUtils::EvaluateString(cx, utf16script, obj, options,
evalOptions, &rval);
nsresult rv = NS_OK;
{
nsJSUtils::ExecutionContext exec(cx, obj);
exec.SetScopeChain(scopeChain);
exec.CompileAndExec(options, utf16script);
rv = exec.ExtractReturnValue(&rval);
}
if (!JS_WrapValue(cx, &rval)) {
return false;
}
return NS_SUCCEEDED(rv) &&
(!result || JSValToNPVariant(npp, cx, rval, result));

View File

@@ -205,9 +205,6 @@ public:
compileOptions.setFileAndLine(NS_ConvertUTF16toUTF8(mURL).get(), 0);
compileOptions.setVersion(JSVERSION_DEFAULT);
compileOptions.setIsRunOnce(true);
// We only need the setNoScriptRval bit when compiling off-thread here,
// since otherwise nsJSUtils::EvaluateString will set it up for us.
compileOptions.setNoScriptRval(true);
JSAutoCompartment comp(cx, globalObj);

View File

@@ -427,14 +427,19 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
JS::CompileOptions options(cx);
options.setFileAndLine(uriSpec.get(), mLineNumber)
.setVersion(JSVERSION_LATEST);
nsJSUtils::EvaluateOptions evalOptions(cx);
if (!nsJSUtils::GetScopeChainForElement(cx, boundElement,
evalOptions.scopeChain)) {
JS::AutoObjectVector scopeChain(cx);
if (!nsJSUtils::GetScopeChainForElement(cx, boundElement, scopeChain)) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = nsJSUtils::EvaluateString(cx, nsDependentString(mFieldText,
mFieldTextLength),
scopeObject, options, evalOptions, &result);
rv = NS_OK;
{
nsJSUtils::ExecutionContext exec(cx, scopeObject);
exec.SetScopeChain(scopeChain);
exec.CompileAndExec(options, nsDependentString(mFieldText,
mFieldTextLength));
rv = exec.ExtractReturnValue(&result);
}
if (NS_FAILED(rv)) {
return rv;
}

View File

@@ -378,6 +378,12 @@ js::AssertSameCompartment(JSContext* cx, JSObject* obj)
assertSameCompartment(cx, obj);
}
JS_FRIEND_API(void)
js::AssertSameCompartment(JSContext* cx, JS::HandleValue v)
{
assertSameCompartment(cx, v);
}
#ifdef DEBUG
JS_FRIEND_API(void)
js::AssertSameCompartment(JSObject* objA, JSObject* objB)

View File

@@ -653,6 +653,9 @@ GetPrototypeNoProxy(JSObject* obj);
JS_FRIEND_API(void)
AssertSameCompartment(JSContext* cx, JSObject* obj);
JS_FRIEND_API(void)
AssertSameCompartment(JSContext* cx, JS::HandleValue v);
#ifdef JS_DEBUG
JS_FRIEND_API(void)
AssertSameCompartment(JSObject* objA, JSObject* objB);