Bug 1724236 - Remove JSExecutionContext r=arai

I think the constructor assertions don't need to be preserved, since the
locations where JSExecutionContext was constructed are obviously using a real
global on the main thread. I'm less confident in removing the check for
CycleCollectedJSContext::Get()->MicroTaskLevel(), but it should be ok since the
assertion wasn't failing already.

I'm leaving the profiler label "JSExecutionContext" intact for now so there's
no change in recorded profiles, but we should consider a better name for it in
the future.

Differential Revision: https://phabricator.services.mozilla.com/D218457
This commit is contained in:
Bryan Thrall
2024-10-30 13:41:46 +00:00
parent 34372a7a97
commit 0b84b732ae
6 changed files with 42 additions and 136 deletions

View File

@@ -13,34 +13,19 @@
#include "mozilla/dom/JSExecutionContext.h" #include "mozilla/dom/JSExecutionContext.h"
#include <utility> #include <utility> // std::move
#include "ErrorList.h" #include "ErrorList.h" // NS_ERROR_OUT_OF_MEMORY, NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW, NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE
#include "MainThreadUtils.h" #include "js/CompilationAndEvaluation.h" // JS::UpdateDebugMetadata
#include "js/CompilationAndEvaluation.h" #include "js/experimental/JSStencil.h" // JS::StartIncrementalEncoding
#include "js/CompileOptions.h" #include "js/SourceText.h" // JS::SourceText, JS::SourceOwnership
#include "js/Conversions.h" #include "jsapi.h" // JS_IsExceptionPending
#include "js/experimental/JSStencil.h" #include "nsTPromiseFlatString.h" // PromiseFlatString
#include "js/HeapAPI.h"
#include "js/ProfilingCategory.h"
#include "js/Promise.h"
#include "js/SourceText.h"
#include "js/Transcoding.h"
#include "js/Value.h"
#include "js/Wrapper.h"
#include "jsapi.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/dom/ScriptLoadContext.h"
#include "mozilla/Likely.h"
#include "nsContentUtils.h"
#include "nsTPromiseFlatString.h"
#include "xpcpublic.h"
#if !defined(DEBUG) && !defined(MOZ_ENABLE_JS_DUMP) #if !defined(DEBUG) && !defined(MOZ_ENABLE_JS_DUMP)
# include "mozilla/StaticPrefs_browser.h" # include "mozilla/StaticPrefs_browser.h"
#endif #endif
using namespace mozilla; using namespace mozilla;
using mozilla::dom::JSExecutionContext;
namespace mozilla::dom { namespace mozilla::dom {
@@ -53,36 +38,10 @@ nsresult EvaluationExceptionToNSResult(ErrorResult& aRv) {
aRv.SuppressException(); aRv.SuppressException();
return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE; return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE;
} }
if (aRv.ErrorCodeIs(NS_ERROR_DOM_NOT_ALLOWED_ERR)) {
aRv.SuppressException();
return NS_OK;
}
// cases like NS_OK, NS_ERROR_DOM_JS_DECODING_ERROR and NS_ERROR_OUT_OF_MEMORY // cases like NS_OK, NS_ERROR_DOM_JS_DECODING_ERROR and NS_ERROR_OUT_OF_MEMORY
return aRv.StealNSResult(); return aRv.StealNSResult();
} }
} // namespace mozilla::dom
JSExecutionContext::JSExecutionContext(
JSContext* aCx, JS::Handle<JSObject*> aGlobal,
JS::CompileOptions& aCompileOptions, ErrorResult& aRv,
JS::Handle<JS::Value> aDebuggerPrivateValue,
JS::Handle<JSScript*> aDebuggerIntroductionScript)
: mSkip(false) {
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(CycleCollectedJSContext::Get() &&
CycleCollectedJSContext::Get()->MicroTaskLevel());
MOZ_ASSERT(JS_IsGlobalObject(aGlobal));
if (MOZ_UNLIKELY(!xpc::Scriptability::Get(aGlobal).Allowed())) {
mSkip = true;
aRv = NS_ERROR_DOM_NOT_ALLOWED_ERR;
}
}
namespace mozilla::dom {
void Compile(JSContext* aCx, JS::CompileOptions& aCompileOptions, void Compile(JSContext* aCx, JS::CompileOptions& aCompileOptions,
const nsAString& aScript, RefPtr<JS::Stencil>& aStencil, const nsAString& aScript, RefPtr<JS::Stencil>& aStencil,
ErrorResult& aRv) { ErrorResult& aRv) {

View File

@@ -7,63 +7,20 @@
#ifndef DOM_BASE_JSEXECUTIONCONTEXT_H_ #ifndef DOM_BASE_JSEXECUTIONCONTEXT_H_
#define DOM_BASE_JSEXECUTIONCONTEXT_H_ #define DOM_BASE_JSEXECUTIONCONTEXT_H_
#include "js/GCVector.h" #include "js/TypeDecls.h" // JSScript, MutableHandle
#include "js/TypeDecls.h" #include "js/Value.h" // JS::UndefinedHandleValue
#include "js/Value.h" #include "js/experimental/JSStencil.h" // JS::Stencil
#include "js/experimental/JSStencil.h" #include "js/CompileOptions.h" // JS::CompileOptions
#include "jsapi.h" #include "js/RootingAPI.h" // JS::Handle
#include "mozilla/Assertions.h" #include "mozilla/ErrorResult.h" // ErrorResult
#include "mozilla/Attributes.h" #include "nsStringFwd.h" // nsAString
#include "mozilla/ErrorResult.h"
#include "mozilla/ProfilerLabels.h"
#include "mozilla/Vector.h"
#include "nsStringFwd.h"
#include "nscore.h"
class nsIScriptContext;
class nsIScriptElement;
class nsIScriptGlobalObject;
class nsXBLPrototypeBinding;
namespace mozilla { namespace mozilla {
union Utf8Unit;
namespace dom { namespace dom {
class ScriptLoadContext;
nsresult EvaluationExceptionToNSResult(ErrorResult& aRv); nsresult EvaluationExceptionToNSResult(ErrorResult& aRv);
class MOZ_STACK_CLASS JSExecutionContext final {
// Used to skip upcoming phases in case of a failure. In such case the
// result is carried by mRv.
bool mSkip;
public:
// Enter compartment in which the code would be executed. The JSContext
// must come from an AutoEntryScript.
//
// The JS engine can associate metadata for the debugger with scripts at
// compile time. The optional last arguments here cover that metadata.
JSExecutionContext(
JSContext* aCx, JS::Handle<JSObject*> aGlobal,
JS::CompileOptions& aCompileOptions, ErrorResult& aRv,
JS::Handle<JS::Value> aDebuggerPrivateValue = JS::UndefinedHandleValue,
JS::Handle<JSScript*> aDebuggerIntroductionScript = nullptr);
JSExecutionContext(const JSExecutionContext&) = delete;
JSExecutionContext(JSExecutionContext&&) = delete;
~JSExecutionContext() {
// This flag is reset when the returned value is extracted.
// 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);
}
};
// Compile a script contained in a string. // Compile a script contained in a string.
void Compile(JSContext* aCx, JS::CompileOptions& aCompileOptions, void Compile(JSContext* aCx, JS::CompileOptions& aCompileOptions,
const nsAString& aScript, RefPtr<JS::Stencil>& aStencil, const nsAString& aScript, RefPtr<JS::Stencil>& aStencil,

View File

@@ -6094,8 +6094,7 @@ bool WindowScriptTimeoutHandler::Call(const char* aExecutionReason) {
JS::Rooted<JSObject*> global(aes.cx(), mGlobal->GetGlobalJSObject()); JS::Rooted<JSObject*> global(aes.cx(), mGlobal->GetGlobalJSObject());
{ {
IgnoredErrorResult erv; IgnoredErrorResult erv;
JSExecutionContext exec(aes.cx(), global, options, erv); if (MOZ_LIKELY(xpc::Scriptability::Get(global).Allowed())) {
if (!erv.Failed()) {
mozilla::AutoProfilerLabel autoProfilerLabel( mozilla::AutoProfilerLabel autoProfilerLabel(
"JSExecutionContext", "JSExecutionContext",
/* dynamicStr */ nullptr, JS::ProfilingCategoryPair::JS); /* dynamicStr */ nullptr, JS::ProfilingCategoryPair::JS);

View File

@@ -59,7 +59,6 @@
using mozilla::IsAscii; using mozilla::IsAscii;
using mozilla::dom::AutoEntryScript; using mozilla::dom::AutoEntryScript;
using mozilla::dom::JSExecutionContext;
static NS_DEFINE_CID(kJSURICID, NS_JSURI_CID); static NS_DEFINE_CID(kJSURICID, NS_JSURI_CID);
@@ -191,10 +190,9 @@ static bool IsPromiseValue(JSContext* aCx, JS::Handle<JS::Value> aValue) {
// result to a string, the nsresult is 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 remains 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 |aCx|'s
// compartment given as argument to the JSExecutionContext constructor. If the // compartment. If the caller is in a different compartment, then the out-param
// caller is in a different compartment, then the out-param value should be // value should be wrapped by calling |JS_WrapValue|.
// wrapped by calling |JS_WrapValue|.
// //
static void ExecScriptAndCoerceToString(JSContext* aCx, static void ExecScriptAndCoerceToString(JSContext* aCx,
JS::Handle<JSScript*> aScript, JS::Handle<JSScript*> aScript,
@@ -386,8 +384,7 @@ nsresult nsJSThunk::EvaluateScript(
options.setIntroductionType("javascriptURL"); options.setIntroductionType("javascriptURL");
{ {
mozilla::ErrorResult erv; mozilla::ErrorResult erv;
JSExecutionContext exec(cx, globalJSObject, options, erv); if (MOZ_LIKELY(xpc::Scriptability::Get(globalJSObject).Allowed())) {
if (!erv.Failed()) {
mozilla::AutoProfilerLabel autoProfilerLabel( mozilla::AutoProfilerLabel autoProfilerLabel(
"JSExecutionContext", "JSExecutionContext",
/* dynamicStr */ nullptr, JS::ProfilingCategoryPair::JS); /* dynamicStr */ nullptr, JS::ProfilingCategoryPair::JS);

View File

@@ -2743,10 +2743,9 @@ static void Decode(JSContext* aCx, JS::CompileOptions& aCompileOptions,
} }
void ScriptLoader::InstantiateClassicScriptFromMaybeEncodedSource( void ScriptLoader::InstantiateClassicScriptFromMaybeEncodedSource(
JSContext* aCx, JSExecutionContext& aExec, JSContext* aCx, JS::CompileOptions& aCompileOptions,
JS::CompileOptions& aCompileOptions, ScriptLoadRequest* aRequest, ScriptLoadRequest* aRequest, JS::MutableHandle<JSScript*> aScript,
JS::MutableHandle<JSScript*> aScript, bool aKeepStencil, bool aKeepStencil, RefPtr<JS::Stencil>& aStencilDup,
RefPtr<JS::Stencil>& aStencilDup,
JS::Handle<JS::Value> aDebuggerPrivateValue, JS::Handle<JS::Value> aDebuggerPrivateValue,
JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv) { JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv) {
nsAutoCString profilerLabelString; nsAutoCString profilerLabelString;
@@ -2885,9 +2884,9 @@ void ScriptLoader::InstantiateClassicScriptFromMaybeEncodedSource(
} }
void ScriptLoader::InstantiateClassicScriptFromCachedStencil( void ScriptLoader::InstantiateClassicScriptFromCachedStencil(
JSContext* aCx, JSExecutionContext& aExec, JSContext* aCx, JS::CompileOptions& aCompileOptions,
JS::CompileOptions& aCompileOptions, ScriptLoadRequest* aRequest, ScriptLoadRequest* aRequest, JS::Stencil* aStencil,
JS::Stencil* aStencil, JS::MutableHandle<JSScript*> aScript, JS::MutableHandle<JSScript*> aScript,
JS::Handle<JS::Value> aDebuggerPrivateValue, JS::Handle<JS::Value> aDebuggerPrivateValue,
JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv) { JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv) {
RefPtr<JS::Stencil> stencil = JS::DuplicateStencil(aCx, aStencil); RefPtr<JS::Stencil> stencil = JS::DuplicateStencil(aCx, aStencil);
@@ -2907,16 +2906,15 @@ void ScriptLoader::InstantiateClassicScriptFromCachedStencil(
} }
void ScriptLoader::InstantiateClassicScriptFromAny( void ScriptLoader::InstantiateClassicScriptFromAny(
JSContext* aCx, JSExecutionContext& aExec, JSContext* aCx, JS::CompileOptions& aCompileOptions,
JS::CompileOptions& aCompileOptions, ScriptLoadRequest* aRequest, ScriptLoadRequest* aRequest, JS::MutableHandle<JSScript*> aScript,
JS::MutableHandle<JSScript*> aScript,
JS::Handle<JS::Value> aDebuggerPrivateValue, JS::Handle<JS::Value> aDebuggerPrivateValue,
JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv) { JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv) {
if (aRequest->IsStencil()) { if (aRequest->IsStencil()) {
RefPtr<JS::Stencil> stencil = aRequest->GetStencil(); RefPtr<JS::Stencil> stencil = aRequest->GetStencil();
InstantiateClassicScriptFromCachedStencil( InstantiateClassicScriptFromCachedStencil(
aCx, aExec, aCompileOptions, aRequest, stencil, aScript, aCx, aCompileOptions, aRequest, stencil, aScript, aDebuggerPrivateValue,
aDebuggerPrivateValue, aDebuggerIntroductionScript, aRv); aDebuggerIntroductionScript, aRv);
return; return;
} }
@@ -2935,7 +2933,7 @@ void ScriptLoader::InstantiateClassicScriptFromAny(
RefPtr<JS::Stencil> stencilDup; RefPtr<JS::Stencil> stencilDup;
InstantiateClassicScriptFromMaybeEncodedSource( InstantiateClassicScriptFromMaybeEncodedSource(
aCx, aExec, aCompileOptions, aRequest, aScript, createCache, stencilDup, aCx, aCompileOptions, aRequest, aScript, createCache, stencilDup,
aDebuggerPrivateValue, aDebuggerIntroductionScript, aRv); aDebuggerPrivateValue, aDebuggerIntroductionScript, aRv);
if (!aRv.Failed()) { if (!aRv.Failed()) {
if (createCache) { if (createCache) {
@@ -3106,18 +3104,16 @@ nsresult ScriptLoader::EvaluateScript(nsIGlobalObject* aGlobalObject,
TRACE_FOR_TEST(aRequest, "scriptloader_execute"); TRACE_FOR_TEST(aRequest, "scriptloader_execute");
JS::Rooted<JSObject*> global(cx, aGlobalObject->GetGlobalJSObject()); JS::Rooted<JSObject*> global(cx, aGlobalObject->GetGlobalJSObject());
ErrorResult erv; if (MOZ_UNLIKELY(!xpc::Scriptability::Get(global).Allowed())) {
JSExecutionContext exec(cx, global, options, erv, classicScriptValue, return NS_OK;
introductionScript);
if (erv.Failed()) {
return EvaluationExceptionToNSResult(erv);
} }
ErrorResult erv;
mozilla::AutoProfilerLabel autoProfilerLabel("JSExecutionContext", mozilla::AutoProfilerLabel autoProfilerLabel("JSExecutionContext",
/* dynamicStr */ nullptr, /* dynamicStr */ nullptr,
JS::ProfilingCategoryPair::JS); JS::ProfilingCategoryPair::JS);
JSAutoRealm autoRealm(cx, global); JSAutoRealm autoRealm(cx, global);
JS::Rooted<JSScript*> script(cx); JS::Rooted<JSScript*> script(cx);
InstantiateClassicScriptFromAny(cx, exec, options, aRequest, &script, InstantiateClassicScriptFromAny(cx, options, aRequest, &script,
classicScriptValue, introductionScript, erv); classicScriptValue, introductionScript, erv);
if (!erv.Failed()) { if (!erv.Failed()) {

View File

@@ -639,9 +639,8 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
// * encoded bytecode // * encoded bytecode
// * cached stencil // * cached stencil
void InstantiateClassicScriptFromAny( void InstantiateClassicScriptFromAny(
JSContext* aCx, JSExecutionContext& aExec, JSContext* aCx, JS::CompileOptions& aCompileOptions,
JS::CompileOptions& aCompileOptions, ScriptLoadRequest* aRequest, ScriptLoadRequest* aRequest, JS::MutableHandle<JSScript*> aScript,
JS::MutableHandle<JSScript*> aScript,
JS::Handle<JS::Value> aDebuggerPrivateValue, JS::Handle<JS::Value> aDebuggerPrivateValue,
JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv); JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv);
@@ -652,19 +651,18 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
// If keepStencil is true and this function is successful, aStencilDup will // If keepStencil is true and this function is successful, aStencilDup will
// contain a copy of the compiled stencil for use by the caller. // contain a copy of the compiled stencil for use by the caller.
void InstantiateClassicScriptFromMaybeEncodedSource( void InstantiateClassicScriptFromMaybeEncodedSource(
JSContext* aCx, JSExecutionContext& aExec, JSContext* aCx, JS::CompileOptions& aCompileOptions,
JS::CompileOptions& aCompileOptions, ScriptLoadRequest* aRequest, ScriptLoadRequest* aRequest, JS::MutableHandle<JSScript*> aScript,
JS::MutableHandle<JSScript*> aScript, bool keepStencil, bool keepStencil, RefPtr<JS::Stencil>& aStencilDup,
RefPtr<JS::Stencil>& aStencilDup,
JS::Handle<JS::Value> aDebuggerPrivateValue, JS::Handle<JS::Value> aDebuggerPrivateValue,
JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv); JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv);
// Instantiate classic script from the following data: // Instantiate classic script from the following data:
// * cached stencil // * cached stencil
void InstantiateClassicScriptFromCachedStencil( void InstantiateClassicScriptFromCachedStencil(
JSContext* aCx, JSExecutionContext& aExec, JSContext* aCx, JS::CompileOptions& aCompileOptions,
JS::CompileOptions& aCompileOptions, ScriptLoadRequest* aRequest, ScriptLoadRequest* aRequest, JS::Stencil* aStencil,
JS::Stencil* aStencil, JS::MutableHandle<JSScript*> aScript, JS::MutableHandle<JSScript*> aScript,
JS::Handle<JS::Value> aDebuggerPrivateValue, JS::Handle<JS::Value> aDebuggerPrivateValue,
JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv); JS::Handle<JSScript*> aDebuggerIntroductionScript, ErrorResult& aRv);