mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-03 13:57:31 +09:00
Issue #1691 - Part 7f: Split up compile and execute so we can use ClassicScript. https://bugzilla.mozilla.org/show_bug.cgi?id=1342012 Refactor nsJSUtils::ExecutionContext to separate compilation and execution steps and allow extraction of compiled JSScript. https://bugzilla.mozilla.org/show_bug.cgi?id=1366773 Move buffer argument from JS::StartIncrementalEncoding to JS::FinishIncrementalEncoding.
(cherry picked from commit d4b520b08b958e116dfeeffdc61f3425610d1ce9)
This commit is contained in:
parent
993476283d
commit
c69a47c393
10 changed files with 154 additions and 125 deletions
|
|
@ -138,12 +138,14 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
|
||||||
, mCompartment(aCx, aGlobal)
|
, mCompartment(aCx, aGlobal)
|
||||||
, mRetValue(aCx)
|
, mRetValue(aCx)
|
||||||
, mScopeChain(aCx)
|
, mScopeChain(aCx)
|
||||||
|
, mScript(aCx)
|
||||||
, mRv(NS_OK)
|
, mRv(NS_OK)
|
||||||
, mSkip(false)
|
, mSkip(false)
|
||||||
, mCoerceToString(false)
|
, mCoerceToString(false)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
, mWantsReturnValue(false)
|
, mWantsReturnValue(false)
|
||||||
, mExpectScopeChain(false)
|
, mExpectScopeChain(false)
|
||||||
|
, mScriptUsed(false)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
|
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
|
||||||
|
|
@ -188,8 +190,7 @@ nsJSUtils::ExecutionContext::SetScopeChain(
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsJSUtils::ExecutionContext::JoinAndExec(void **aOffThreadToken,
|
nsJSUtils::ExecutionContext::JoinCompile(void** aOffThreadToken)
|
||||||
JS::MutableHandle<JSScript*> aScript)
|
|
||||||
{
|
{
|
||||||
if (mSkip) {
|
if (mSkip) {
|
||||||
return mRv;
|
return mRv;
|
||||||
|
|
@ -197,9 +198,16 @@ nsJSUtils::ExecutionContext::JoinAndExec(void **aOffThreadToken,
|
||||||
|
|
||||||
MOZ_ASSERT(!mWantsReturnValue);
|
MOZ_ASSERT(!mWantsReturnValue);
|
||||||
MOZ_ASSERT(!mExpectScopeChain);
|
MOZ_ASSERT(!mExpectScopeChain);
|
||||||
aScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken));
|
MOZ_ASSERT(!mScript);
|
||||||
|
mScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken));
|
||||||
*aOffThreadToken = nullptr; // Mark the token as having been finished.
|
*aOffThreadToken = nullptr; // Mark the token as having been finished.
|
||||||
if (!aScript || !JS_ExecuteScript(mCx, mScopeChain, aScript)) {
|
if (!mScript) {
|
||||||
|
mSkip = true;
|
||||||
|
mRv = EvaluationExceptionToNSResult(mCx);
|
||||||
|
return mRv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StartIncrementalEncoding(mCx, mScript)) {
|
||||||
mSkip = true;
|
mSkip = true;
|
||||||
mRv = EvaluationExceptionToNSResult(mCx);
|
mRv = EvaluationExceptionToNSResult(mCx);
|
||||||
return mRv;
|
return mRv;
|
||||||
|
|
@ -209,22 +217,36 @@ nsJSUtils::ExecutionContext::JoinAndExec(void **aOffThreadToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
|
nsJSUtils::ExecutionContext::Compile(JS::CompileOptions& aCompileOptions,
|
||||||
JS::SourceBufferHolder& aSrcBuf)
|
JS::SourceBufferHolder& aSrcBuf)
|
||||||
{
|
{
|
||||||
if (mSkip) {
|
if (mSkip) {
|
||||||
return mRv;
|
return mRv;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT_IF(aCompileOptions.versionSet,
|
|
||||||
aCompileOptions.version != JSVERSION_UNKNOWN);
|
|
||||||
MOZ_ASSERT(aSrcBuf.get());
|
MOZ_ASSERT(aSrcBuf.get());
|
||||||
MOZ_ASSERT(mRetValue.isUndefined());
|
MOZ_ASSERT(mRetValue.isUndefined());
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
mWantsReturnValue = !aCompileOptions.noScriptRval;
|
mWantsReturnValue = !aCompileOptions.noScriptRval;
|
||||||
#endif
|
#endif
|
||||||
MOZ_ASSERT(!mCoerceToString || mWantsReturnValue);
|
|
||||||
if (!JS::Evaluate(mCx, mScopeChain, aCompileOptions, aSrcBuf, &mRetValue)) {
|
MOZ_ASSERT(!mScript);
|
||||||
|
bool compiled = true;
|
||||||
|
if (mScopeChain.length() == 0) {
|
||||||
|
compiled = JS::Compile(mCx, aCompileOptions, aSrcBuf, &mScript);
|
||||||
|
} else {
|
||||||
|
compiled = JS::CompileForNonSyntacticScope(mCx, aCompileOptions, aSrcBuf,
|
||||||
|
&mScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT_IF(compiled, mScript);
|
||||||
|
if (!compiled) {
|
||||||
|
mSkip = true;
|
||||||
|
mRv = EvaluationExceptionToNSResult(mCx);
|
||||||
|
return mRv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StartIncrementalEncoding(mCx, mScript)) {
|
||||||
mSkip = true;
|
mSkip = true;
|
||||||
mRv = EvaluationExceptionToNSResult(mCx);
|
mRv = EvaluationExceptionToNSResult(mCx);
|
||||||
return mRv;
|
return mRv;
|
||||||
|
|
@ -234,8 +256,8 @@ nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
|
nsJSUtils::ExecutionContext::Compile(JS::CompileOptions& aCompileOptions,
|
||||||
const nsAString& aScript)
|
const nsAString& aScript)
|
||||||
{
|
{
|
||||||
if (mSkip) {
|
if (mSkip) {
|
||||||
return mRv;
|
return mRv;
|
||||||
|
|
@ -244,21 +266,20 @@ nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
|
||||||
const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
|
const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
|
||||||
JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
|
JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
|
||||||
JS::SourceBufferHolder::NoOwnership);
|
JS::SourceBufferHolder::NoOwnership);
|
||||||
return CompileAndExec(aCompileOptions, srcBuf);
|
return Compile(aCompileOptions, srcBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsJSUtils::ExecutionContext::DecodeAndExec(JS::CompileOptions& aCompileOptions,
|
nsJSUtils::ExecutionContext::Decode(JS::CompileOptions& aCompileOptions,
|
||||||
mozilla::Vector<uint8_t>& aBytecodeBuf,
|
mozilla::Vector<uint8_t>& aBytecodeBuf,
|
||||||
size_t aBytecodeIndex)
|
size_t aBytecodeIndex)
|
||||||
{
|
{
|
||||||
if (mSkip) {
|
if (mSkip) {
|
||||||
return mRv;
|
return mRv;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(!mWantsReturnValue);
|
MOZ_ASSERT(!mWantsReturnValue);
|
||||||
JS::Rooted<JSScript*> script(mCx);
|
JS::TranscodeResult tr = JS::DecodeScript(mCx, aBytecodeBuf, &mScript, aBytecodeIndex);
|
||||||
JS::TranscodeResult tr = JS::DecodeScript(mCx, aBytecodeBuf, &script, aBytecodeIndex);
|
|
||||||
// These errors are external parameters which should be handled before the
|
// These errors are external parameters which should be handled before the
|
||||||
// decoding phase, and which are the only reasons why you might want to
|
// decoding phase, and which are the only reasons why you might want to
|
||||||
// fallback on decoding failures.
|
// fallback on decoding failures.
|
||||||
|
|
@ -270,17 +291,11 @@ nsJSUtils::ExecutionContext::DecodeAndExec(JS::CompileOptions& aCompileOptions,
|
||||||
return mRv;
|
return mRv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!JS_ExecuteScript(mCx, mScopeChain, script)) {
|
|
||||||
mSkip = true;
|
|
||||||
mRv = EvaluationExceptionToNSResult(mCx);
|
|
||||||
return mRv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mRv;
|
return mRv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsJSUtils::ExecutionContext::DecodeJoinAndExec(void **aOffThreadToken)
|
nsJSUtils::ExecutionContext::JoinDecode(void **aOffThreadToken)
|
||||||
{
|
{
|
||||||
if (mSkip) {
|
if (mSkip) {
|
||||||
return mRv;
|
return mRv;
|
||||||
|
|
@ -288,10 +303,35 @@ nsJSUtils::ExecutionContext::DecodeJoinAndExec(void **aOffThreadToken)
|
||||||
|
|
||||||
MOZ_ASSERT(!mWantsReturnValue);
|
MOZ_ASSERT(!mWantsReturnValue);
|
||||||
MOZ_ASSERT(!mExpectScopeChain);
|
MOZ_ASSERT(!mExpectScopeChain);
|
||||||
JS::Rooted<JSScript*> script(mCx);
|
mScript.set(JS::FinishOffThreadScriptDecoder(mCx, *aOffThreadToken));
|
||||||
script.set(JS::FinishOffThreadScriptDecoder(mCx, *aOffThreadToken));
|
|
||||||
*aOffThreadToken = nullptr; // Mark the token as having been finished.
|
*aOffThreadToken = nullptr; // Mark the token as having been finished.
|
||||||
if (!script || !JS_ExecuteScript(mCx, mScopeChain, script)) {
|
if (!mScript) {
|
||||||
|
mSkip = true;
|
||||||
|
mRv = EvaluationExceptionToNSResult(mCx);
|
||||||
|
return mRv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSScript* nsJSUtils::ExecutionContext::GetScript() {
|
||||||
|
#ifdef DEBUG
|
||||||
|
MOZ_ASSERT(!mSkip);
|
||||||
|
MOZ_ASSERT(mScript);
|
||||||
|
mScriptUsed = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return mScript;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsJSUtils::ExecutionContext::ExecScript() {
|
||||||
|
if (mSkip) {
|
||||||
|
return mRv;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(mScript);
|
||||||
|
|
||||||
|
if (!JS_ExecuteScript(mCx, mScopeChain, mScript)) {
|
||||||
mSkip = true;
|
mSkip = true;
|
||||||
mRv = EvaluationExceptionToNSResult(mCx);
|
mRv = EvaluationExceptionToNSResult(mCx);
|
||||||
return mRv;
|
return mRv;
|
||||||
|
|
@ -301,53 +341,26 @@ nsJSUtils::ExecutionContext::DecodeJoinAndExec(void **aOffThreadToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsJSUtils::ExecutionContext::JoinEncodeAndExec(void **aOffThreadToken,
|
nsJSUtils::ExecutionContext::ExecScript(JS::MutableHandle<JS::Value> aRetValue)
|
||||||
mozilla::Vector<uint8_t>& aBytecodeBuf,
|
|
||||||
JS::MutableHandle<JSScript*> aScript)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT_IF(aOffThreadToken, !mWantsReturnValue);
|
|
||||||
aScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken));
|
|
||||||
*aOffThreadToken = nullptr; // Mark the token as having been finished.
|
|
||||||
if (!aScript) {
|
|
||||||
mSkip = true;
|
|
||||||
mRv = EvaluationExceptionToNSResult(mCx);
|
|
||||||
return mRv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StartIncrementalEncoding(mCx, aBytecodeBuf, aScript)) {
|
|
||||||
mSkip = true;
|
|
||||||
mRv = EvaluationExceptionToNSResult(mCx);
|
|
||||||
return mRv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!JS_ExecuteScript(mCx, mScopeChain, aScript)) {
|
|
||||||
mSkip = true;
|
|
||||||
mRv = EvaluationExceptionToNSResult(mCx);
|
|
||||||
return mRv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mRv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsJSUtils::ExecutionContext::ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(aRetValue.isUndefined());
|
|
||||||
if (mSkip) {
|
if (mSkip) {
|
||||||
// Repeat earlier result, as NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW are not
|
return mRv;
|
||||||
// failures cases.
|
}
|
||||||
#ifdef DEBUG
|
|
||||||
mWantsReturnValue = false;
|
MOZ_ASSERT(mScript);
|
||||||
#endif
|
MOZ_ASSERT(mWantsReturnValue);
|
||||||
|
|
||||||
|
if (!JS_ExecuteScript(mCx, mScopeChain, mScript, aRetValue)) {
|
||||||
|
mSkip = true;
|
||||||
|
mRv = EvaluationExceptionToNSResult(mCx);
|
||||||
return mRv;
|
return mRv;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(mWantsReturnValue);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
mWantsReturnValue = false;
|
mWantsReturnValue = false;
|
||||||
#endif
|
#endif
|
||||||
if (mCoerceToString && !mRetValue.isUndefined()) {
|
if (mCoerceToString && !aRetValue.isUndefined()) {
|
||||||
JSString* str = JS::ToString(mCx, mRetValue);
|
JSString* str = JS::ToString(mCx, aRetValue);
|
||||||
if (!str) {
|
if (!str) {
|
||||||
// ToString can be a function call, so an exception can be raised while
|
// ToString can be a function call, so an exception can be raised while
|
||||||
// executing the function.
|
// executing the function.
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,9 @@ public:
|
||||||
// Scope chain in which the execution takes place.
|
// Scope chain in which the execution takes place.
|
||||||
JS::AutoObjectVector mScopeChain;
|
JS::AutoObjectVector mScopeChain;
|
||||||
|
|
||||||
|
// The compiled script.
|
||||||
|
JS::Rooted<JSScript*> mScript;
|
||||||
|
|
||||||
// returned value forwarded when we have to interupt the execution eagerly
|
// returned value forwarded when we have to interupt the execution eagerly
|
||||||
// with mSkip.
|
// with mSkip.
|
||||||
nsresult mRv;
|
nsresult mRv;
|
||||||
|
|
@ -92,6 +95,8 @@ public:
|
||||||
bool mWantsReturnValue;
|
bool mWantsReturnValue;
|
||||||
|
|
||||||
bool mExpectScopeChain;
|
bool mExpectScopeChain;
|
||||||
|
|
||||||
|
bool mScriptUsed;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -105,8 +110,12 @@ public:
|
||||||
ExecutionContext(ExecutionContext&&) = delete;
|
ExecutionContext(ExecutionContext&&) = delete;
|
||||||
|
|
||||||
~ExecutionContext() {
|
~ExecutionContext() {
|
||||||
// This flag is resetted, when the returned value is extracted.
|
// This flag is reset when the returned value is extracted.
|
||||||
MOZ_ASSERT(!mWantsReturnValue);
|
MOZ_ASSERT_IF(!mSkip, !mWantsReturnValue);
|
||||||
|
|
||||||
|
// If encoding was started we expect the script to have been
|
||||||
|
// used when ending the encoding.
|
||||||
|
MOZ_ASSERT_IF(mEncodeBytecode && mScript && mRv == NS_OK, mScriptUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The returned value would be converted to a string if the
|
// The returned value would be converted to a string if the
|
||||||
|
|
@ -119,10 +128,41 @@ public:
|
||||||
// Set the scope chain in which the code should be executed.
|
// Set the scope chain in which the code should be executed.
|
||||||
void SetScopeChain(const JS::AutoObjectVector& aScopeChain);
|
void SetScopeChain(const JS::AutoObjectVector& aScopeChain);
|
||||||
|
|
||||||
// Copy the returned value in the mutable handle argument, in case of a
|
// After getting a notification that an off-thread compilation terminated,
|
||||||
|
// this function will take the result of the parser and move it to the main
|
||||||
|
// thread.
|
||||||
|
MOZ_MUST_USE nsresult JoinCompile(void** aOffThreadToken);
|
||||||
|
|
||||||
|
// Compile a script contained in a SourceText.
|
||||||
|
nsresult Compile(JS::CompileOptions& aCompileOptions,
|
||||||
|
JS::SourceBufferHolder& aSrcBuf);
|
||||||
|
|
||||||
|
// Compile a script contained in a string.
|
||||||
|
nsresult Compile(JS::CompileOptions& aCompileOptions,
|
||||||
|
const nsAString& aScript);
|
||||||
|
|
||||||
|
// Decode a script contained in a buffer.
|
||||||
|
nsresult Decode(JS::CompileOptions& aCompileOptions,
|
||||||
|
mozilla::Vector<uint8_t>& aBytecodeBuf,
|
||||||
|
size_t aBytecodeIndex);
|
||||||
|
|
||||||
|
// After getting a notification that an off-thread decoding terminated, this
|
||||||
|
// function will get the result of the decoder and move it to the main
|
||||||
|
// thread.
|
||||||
|
nsresult JoinDecode(void** aOffThreadToken);
|
||||||
|
|
||||||
|
// Get a successfully compiled script.
|
||||||
|
JSScript* GetScript();
|
||||||
|
|
||||||
|
// Execute the compiled script and ignore the return value.
|
||||||
|
MOZ_MUST_USE nsresult ExecScript();
|
||||||
|
|
||||||
|
// Execute the compiled script a get the return value.
|
||||||
|
//
|
||||||
|
// Copy the returned value into the mutable handle argument. In case of a
|
||||||
// evaluation failure either during the execution or the conversion of the
|
// evaluation failure either during the execution or the conversion of the
|
||||||
// result to a string, the nsresult would be set to the corresponding result
|
// result to a string, the nsresult is be set to the corresponding result
|
||||||
// code, and the mutable handle argument would remain unchanged.
|
// code and the mutable handle argument remains unchanged.
|
||||||
//
|
//
|
||||||
// The value returned in the mutable handle argument is part of the
|
// The value returned in the mutable handle argument is part of the
|
||||||
// compartment given as argument to the ExecutionContext constructor. If the
|
// compartment given as argument to the ExecutionContext constructor. If the
|
||||||
|
|
@ -131,37 +171,7 @@ public:
|
||||||
MOZ_MUST_USE nsresult
|
MOZ_MUST_USE nsresult
|
||||||
ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue);
|
ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue);
|
||||||
|
|
||||||
// After getting a notification that an off-thread compilation terminated,
|
MOZ_MUST_USE nsresult ExecScript(JS::MutableHandle<JS::Value> aRetValue);
|
||||||
// this function will take the result of the parser by moving it to the main
|
|
||||||
// thread before starting the execution of the script.
|
|
||||||
//
|
|
||||||
// The compiled script would be returned in the |aScript| out-param.
|
|
||||||
MOZ_MUST_USE nsresult JoinAndExec(void **aOffThreadToken,
|
|
||||||
JS::MutableHandle<JSScript*> aScript);
|
|
||||||
|
|
||||||
// Compile a script contained in a SourceBuffer, and execute it.
|
|
||||||
nsresult CompileAndExec(JS::CompileOptions& aCompileOptions,
|
|
||||||
JS::SourceBufferHolder& aSrcBuf);
|
|
||||||
|
|
||||||
// Compile a script contained in a string, and execute it.
|
|
||||||
nsresult CompileAndExec(JS::CompileOptions& aCompileOptions,
|
|
||||||
const nsAString& aScript);
|
|
||||||
|
|
||||||
// Decode a script contained in a buffer, and execute it.
|
|
||||||
MOZ_MUST_USE nsresult DecodeAndExec(JS::CompileOptions& aCompileOptions,
|
|
||||||
mozilla::Vector<uint8_t>& aBytecodeBuf,
|
|
||||||
size_t aBytecodeIndex);
|
|
||||||
|
|
||||||
// After getting a notification that an off-thread decoding terminated, this
|
|
||||||
// function will get the result of the decoder by moving it to the main
|
|
||||||
// thread before starting the execution of the script.
|
|
||||||
MOZ_MUST_USE nsresult DecodeJoinAndExec(void **aOffThreadToken);
|
|
||||||
|
|
||||||
// Similar to JoinAndExec, except that in addition to fecthing the source,
|
|
||||||
// we register the fact that we plan to encode its bytecode later.
|
|
||||||
MOZ_MUST_USE nsresult JoinEncodeAndExec(void **aOffThreadToken,
|
|
||||||
mozilla::Vector<uint8_t>& aBytecodeBuf,
|
|
||||||
JS::MutableHandle<JSScript*> aScript);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MOZ_STACK_CLASS EvaluateOptions {
|
struct MOZ_STACK_CLASS EvaluateOptions {
|
||||||
|
|
|
||||||
|
|
@ -2348,12 +2348,23 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
|
||||||
{
|
{
|
||||||
nsJSUtils::ExecutionContext exec(cx, global);
|
nsJSUtils::ExecutionContext exec(cx, global);
|
||||||
if (aRequest->mOffThreadToken) {
|
if (aRequest->mOffThreadToken) {
|
||||||
JS::Rooted<JSScript*> script(cx);
|
rv = exec.JoinDecode(&aRequest->mOffThreadToken);
|
||||||
rv = exec.JoinAndExec(&aRequest->mOffThreadToken, &script);
|
|
||||||
} else {
|
} else {
|
||||||
nsAutoString inlineData;
|
nsAutoString inlineData;
|
||||||
SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
|
SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
|
||||||
rv = exec.CompileAndExec(options, srcBuf);
|
rv = exec.Compile(options, srcBuf);
|
||||||
|
}
|
||||||
|
if (rv == NS_OK) {
|
||||||
|
JS::Rooted<JSScript*> script(cx);
|
||||||
|
script = exec.GetScript();
|
||||||
|
|
||||||
|
// Create a ClassicScript object and associate it with the
|
||||||
|
// JSScript.
|
||||||
|
RefPtr<ClassicScript> classicScript = new ClassicScript(
|
||||||
|
aRequest->mFetchOptions, aRequest->mBaseURL);
|
||||||
|
classicScript->AssociateWithScript(script);
|
||||||
|
|
||||||
|
rv = exec.ExecScript();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7127,21 +7127,21 @@ JS::DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(bool)
|
JS_PUBLIC_API(bool)
|
||||||
JS::StartIncrementalEncoding(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script)
|
JS::StartIncrementalEncoding(JSContext* cx, JS::HandleScript script)
|
||||||
{
|
{
|
||||||
if (!script)
|
if (!script)
|
||||||
return false;
|
return false;
|
||||||
if (!script->scriptSource()->xdrEncodeTopLevel(cx, buffer, script))
|
if (!script->scriptSource()->xdrEncodeTopLevel(cx, script))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(bool)
|
JS_PUBLIC_API(bool)
|
||||||
JS::FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script)
|
JS::FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script, TranscodeBuffer& buffer)
|
||||||
{
|
{
|
||||||
if (!script)
|
if (!script)
|
||||||
return false;
|
return false;
|
||||||
if (!script->scriptSource()->xdrFinalizeEncoder())
|
if (!script->scriptSource()->xdrFinalizeEncoder(buffer))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6209,15 +6209,14 @@ DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHan
|
||||||
// an out-param of any of the |Compile| functions, or the result of
|
// an out-param of any of the |Compile| functions, or the result of
|
||||||
// |FinishOffThreadScript|.
|
// |FinishOffThreadScript|.
|
||||||
//
|
//
|
||||||
// The |buffer| argument should not be used before until
|
// The |buffer| argument of |FinishIncrementalEncoding| is used for appending
|
||||||
// |FinishIncrementalEncoding| is called on the same script, and returns
|
// the encoded bytecode into the buffer. If any of these functions failed, the
|
||||||
// successfully. If any of these functions failed, the |buffer| content is
|
// content of |buffer| would be undefined.
|
||||||
// undefined.
|
|
||||||
extern JS_PUBLIC_API(bool)
|
extern JS_PUBLIC_API(bool)
|
||||||
StartIncrementalEncoding(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script);
|
StartIncrementalEncoding(JSContext* cx, JS::HandleScript script);
|
||||||
|
|
||||||
extern JS_PUBLIC_API(bool)
|
extern JS_PUBLIC_API(bool)
|
||||||
FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script);
|
FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script, TranscodeBuffer& buffer);
|
||||||
|
|
||||||
} /* namespace JS */
|
} /* namespace JS */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1958,10 +1958,9 @@ ScriptSource::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ScriptSource::xdrEncodeTopLevel(ExclusiveContext* cx, JS::TranscodeBuffer& buffer,
|
ScriptSource::xdrEncodeTopLevel(ExclusiveContext* cx, HandleScript script)
|
||||||
HandleScript script)
|
|
||||||
{
|
{
|
||||||
xdrEncoder_ = js::MakeUnique<XDRIncrementalEncoder>(cx, buffer, buffer.length());
|
xdrEncoder_ = js::MakeUnique<XDRIncrementalEncoder>(cx);
|
||||||
if (!xdrEncoder_) {
|
if (!xdrEncoder_) {
|
||||||
ReportOutOfMemory(cx);
|
ReportOutOfMemory(cx);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -2003,14 +2002,14 @@ ScriptSource::xdrEncodeFunction(ExclusiveContext* cx, HandleFunction fun, Handle
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ScriptSource::xdrFinalizeEncoder()
|
ScriptSource::xdrFinalizeEncoder(JS::TranscodeBuffer& buffer)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(hasEncoder());
|
MOZ_ASSERT(hasEncoder());
|
||||||
auto cleanup = mozilla::MakeScopeExit([&] {
|
auto cleanup = mozilla::MakeScopeExit([&] {
|
||||||
xdrEncoder_.reset(nullptr);
|
xdrEncoder_.reset(nullptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!xdrEncoder_->linearize())
|
if (!xdrEncoder_->linearize(buffer))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -588,7 +588,7 @@ class ScriptSource
|
||||||
// of the encoding would be available in the |buffer| provided as argument,
|
// of the encoding would be available in the |buffer| provided as argument,
|
||||||
// as soon as |xdrFinalize| is called and all xdr function calls returned
|
// as soon as |xdrFinalize| is called and all xdr function calls returned
|
||||||
// successfully.
|
// successfully.
|
||||||
bool xdrEncodeTopLevel(ExclusiveContext* cx, JS::TranscodeBuffer& buffer, HandleScript script);
|
bool xdrEncodeTopLevel(ExclusiveContext* cx, HandleScript script);
|
||||||
|
|
||||||
// Encode a delazified JSFunction. In case of errors, the XDR encoder is
|
// Encode a delazified JSFunction. In case of errors, the XDR encoder is
|
||||||
// freed and the |buffer| provided as argument to |xdrEncodeTopLevel| is
|
// freed and the |buffer| provided as argument to |xdrEncodeTopLevel| is
|
||||||
|
|
@ -602,7 +602,7 @@ class ScriptSource
|
||||||
// Linearize the encoded content in the |buffer| provided as argument to
|
// Linearize the encoded content in the |buffer| provided as argument to
|
||||||
// |xdrEncodeTopLevel|, and free the XDR encoder. In case of errors, the
|
// |xdrEncodeTopLevel|, and free the XDR encoder. In case of errors, the
|
||||||
// |buffer| is considered undefined.
|
// |buffer| is considered undefined.
|
||||||
bool xdrFinalizeEncoder();
|
bool xdrFinalizeEncoder(JS::TranscodeBuffer& buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScriptSourceHolder
|
class ScriptSourceHolder
|
||||||
|
|
|
||||||
|
|
@ -1774,7 +1774,7 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
|
||||||
// register ahead the fact that every JSFunction which is being
|
// register ahead the fact that every JSFunction which is being
|
||||||
// delazified should be encoded at the end of the delazification.
|
// delazified should be encoded at the end of the delazification.
|
||||||
if (saveIncrementalBytecode) {
|
if (saveIncrementalBytecode) {
|
||||||
if (!StartIncrementalEncoding(cx, saveBuffer, script))
|
if (!StartIncrementalEncoding(cx, script))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1799,7 +1799,7 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
|
||||||
// Serialize the encoded bytecode, recorded before the execution, into a
|
// Serialize the encoded bytecode, recorded before the execution, into a
|
||||||
// buffer which can be deserialized linearly.
|
// buffer which can be deserialized linearly.
|
||||||
if (saveIncrementalBytecode) {
|
if (saveIncrementalBytecode) {
|
||||||
if (!FinishIncrementalEncoding(cx, script))
|
if (!FinishIncrementalEncoding(cx, script, saveBuffer))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,7 @@ XDRIncrementalEncoder::endSubTree()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
XDRIncrementalEncoder::linearize()
|
XDRIncrementalEncoder::linearize(JS::TranscodeBuffer& buffer)
|
||||||
{
|
{
|
||||||
if (oom_) {
|
if (oom_) {
|
||||||
ReportOutOfMemory(cx());
|
ReportOutOfMemory(cx());
|
||||||
|
|
@ -343,7 +343,7 @@ XDRIncrementalEncoder::linearize()
|
||||||
// buffer which would be serialized.
|
// buffer which would be serialized.
|
||||||
MOZ_ASSERT(slice.sliceBegin <= slices_.length());
|
MOZ_ASSERT(slice.sliceBegin <= slices_.length());
|
||||||
MOZ_ASSERT(slice.sliceBegin + slice.sliceLength <= slices_.length());
|
MOZ_ASSERT(slice.sliceBegin + slice.sliceLength <= slices_.length());
|
||||||
if (!buffer_.append(slices_.begin() + slice.sliceBegin, slice.sliceLength)) {
|
if (!buffer.append(slices_.begin() + slice.sliceBegin, slice.sliceLength)) {
|
||||||
ReportOutOfMemory(cx());
|
ReportOutOfMemory(cx());
|
||||||
return fail(JS::TranscodeResult_Throw);
|
return fail(JS::TranscodeResult_Throw);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -410,18 +410,15 @@ class XDRIncrementalEncoder : public XDREncoder
|
||||||
// Tree of slices.
|
// Tree of slices.
|
||||||
SlicesTree tree_;
|
SlicesTree tree_;
|
||||||
JS::TranscodeBuffer slices_;
|
JS::TranscodeBuffer slices_;
|
||||||
JS::TranscodeBuffer& buffer_;
|
|
||||||
bool oom_;
|
bool oom_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XDRIncrementalEncoder(ExclusiveContext* cx, JS::TranscodeBuffer& buffer, size_t cursor)
|
XDRIncrementalEncoder(ExclusiveContext* cx)
|
||||||
: XDREncoder(cx, slices_, 0),
|
: XDREncoder(cx, slices_, 0),
|
||||||
scope_(nullptr),
|
scope_(nullptr),
|
||||||
node_(nullptr),
|
node_(nullptr),
|
||||||
buffer_(buffer),
|
|
||||||
oom_(false)
|
oom_(false)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(buffer.length() == cursor, "NYI");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~XDRIncrementalEncoder() {}
|
virtual ~XDRIncrementalEncoder() {}
|
||||||
|
|
@ -434,9 +431,9 @@ class XDRIncrementalEncoder : public XDREncoder
|
||||||
void createOrReplaceSubTree(AutoXDRTree* child) override;
|
void createOrReplaceSubTree(AutoXDRTree* child) override;
|
||||||
void endSubTree() override;
|
void endSubTree() override;
|
||||||
|
|
||||||
// In the current XDRBuffer, move replaceable-parts to form a linear
|
// Append the content collected during the incremental encoding into the
|
||||||
// sequence of bytes.
|
// buffer given as argument.
|
||||||
MOZ_MUST_USE bool linearize();
|
MOZ_MUST_USE bool linearize(JS::TranscodeBuffer& buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue