From 9d6255073deb8f55fe7dfa063d6f7e639b9d3cd6 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 8 Aug 2018 10:40:03 +0100 Subject: [PATCH] Bug 1481196 - Compile module scripts to a JSScript like we do for classic scripts r=jandem r=baku --- dom/base/nsJSUtils.cpp | 21 +++++----- dom/base/nsJSUtils.h | 8 ++-- dom/script/ModuleScript.cpp | 36 ++++++++--------- dom/script/ModuleScript.h | 8 ++-- dom/script/ScriptLoader.cpp | 57 ++++++++++++++------------- dom/script/ScriptLoader.h | 4 +- js/public/Realm.h | 5 +++ js/src/builtin/ModuleObject.cpp | 7 ++-- js/src/builtin/ModuleObject.h | 2 +- js/src/frontend/BytecodeCompiler.cpp | 23 +++++------ js/src/frontend/BytecodeCompiler.h | 5 +-- js/src/jit/BaselineCompiler.cpp | 3 +- js/src/jsapi.cpp | 58 ++++++++++++++++------------ js/src/jsapi.h | 29 +++++++------- js/src/shell/js.cpp | 25 ++++++------ js/src/vm/HelperThreads.cpp | 12 +++--- js/src/vm/HelperThreads.h | 2 +- js/src/vm/Interpreter.cpp | 3 +- js/src/vm/Realm.cpp | 6 +++ js/src/vm/SelfHosting.cpp | 11 +++--- js/xpconnect/src/XPCJSRuntime.cpp | 7 ++++ js/xpconnect/src/xpcprivate.h | 7 ++++ js/xpconnect/src/xpcpublic.h | 1 + 23 files changed, 191 insertions(+), 149 deletions(-) diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp index fb5552c0d961..b408c0a7dc94 100644 --- a/dom/base/nsJSUtils.cpp +++ b/dom/base/nsJSUtils.cpp @@ -473,7 +473,7 @@ nsJSUtils::CompileModule(JSContext* aCx, JS::SourceBufferHolder& aSrcBuf, JS::Handle aEvaluationGlobal, JS::CompileOptions &aCompileOptions, - JS::MutableHandle aModule) + JS::MutableHandle aScript) { AUTO_PROFILER_LABEL("nsJSUtils::CompileModule", JS); @@ -487,7 +487,7 @@ nsJSUtils::CompileModule(JSContext* aCx, NS_ENSURE_TRUE(xpc::Scriptability::Get(aEvaluationGlobal).Allowed(), NS_OK); - if (!JS::CompileModule(aCx, aCompileOptions, aSrcBuf, aModule)) { + if (!JS::CompileModule(aCx, aCompileOptions, aSrcBuf, aScript)) { return NS_ERROR_FAILURE; } @@ -496,7 +496,7 @@ nsJSUtils::CompileModule(JSContext* aCx, nsresult nsJSUtils::InitModuleSourceElement(JSContext* aCx, - JS::Handle aModule, + JS::Handle aScript, nsIScriptElement* aElement) { JS::Rooted value(aCx); @@ -509,8 +509,7 @@ nsJSUtils::InitModuleSourceElement(JSContext* aCx, MOZ_ASSERT(value.isObject()); JS::Rooted object(aCx, &value.toObject()); - JS::Rooted script(aCx, JS::GetModuleScript(aModule)); - if (!JS::InitScriptSourceElement(aCx, script, object, nullptr)) { + if (!JS::InitScriptSourceElement(aCx, aScript, object, nullptr)) { return NS_ERROR_FAILURE; } @@ -518,7 +517,7 @@ nsJSUtils::InitModuleSourceElement(JSContext* aCx, } nsresult -nsJSUtils::ModuleInstantiate(JSContext* aCx, JS::Handle aModule) +nsJSUtils::ModuleInstantiate(JSContext* aCx, JS::Handle aScript) { AUTO_PROFILER_LABEL("nsJSUtils::ModuleInstantiate", JS); @@ -527,9 +526,9 @@ nsJSUtils::ModuleInstantiate(JSContext* aCx, JS::Handle aModule) MOZ_ASSERT(CycleCollectedJSContext::Get() && CycleCollectedJSContext::Get()->MicroTaskLevel()); - NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK); + NS_ENSURE_TRUE(xpc::Scriptability::Get(aScript).Allowed(), NS_OK); - if (!JS::ModuleInstantiate(aCx, aModule)) { + if (!JS::ModuleInstantiate(aCx, aScript)) { return NS_ERROR_FAILURE; } @@ -537,7 +536,7 @@ nsJSUtils::ModuleInstantiate(JSContext* aCx, JS::Handle aModule) } nsresult -nsJSUtils::ModuleEvaluate(JSContext* aCx, JS::Handle aModule) +nsJSUtils::ModuleEvaluate(JSContext* aCx, JS::Handle aScript) { AUTO_PROFILER_LABEL("nsJSUtils::ModuleEvaluate", JS); @@ -546,9 +545,9 @@ nsJSUtils::ModuleEvaluate(JSContext* aCx, JS::Handle aModule) MOZ_ASSERT(CycleCollectedJSContext::Get() && CycleCollectedJSContext::Get()->MicroTaskLevel()); - NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK); + NS_ENSURE_TRUE(xpc::Scriptability::Get(aScript).Allowed(), NS_OK); - if (!JS::ModuleEvaluate(aCx, aModule)) { + if (!JS::ModuleEvaluate(aCx, aScript)) { return NS_ERROR_FAILURE; } diff --git a/dom/base/nsJSUtils.h b/dom/base/nsJSUtils.h index a4b4cb4a87de..6de2bc6ac7dc 100644 --- a/dom/base/nsJSUtils.h +++ b/dom/base/nsJSUtils.h @@ -189,17 +189,17 @@ public: JS::SourceBufferHolder& aSrcBuf, JS::Handle aEvaluationGlobal, JS::CompileOptions &aCompileOptions, - JS::MutableHandle aModule); + JS::MutableHandle aScript); static nsresult InitModuleSourceElement(JSContext* aCx, - JS::Handle aModule, + JS::Handle aScript, nsIScriptElement* aElement); static nsresult ModuleInstantiate(JSContext* aCx, - JS::Handle aModule); + JS::Handle aScript); static nsresult ModuleEvaluate(JSContext* aCx, - JS::Handle aModule); + JS::Handle aScript); // Returns false if an exception got thrown on aCx. Passing a null // aElement is allowed; that wil produce an empty aScopeChain. diff --git a/dom/script/ModuleScript.cpp b/dom/script/ModuleScript.cpp index 35b188ab8df2..949a68f9bc48 100644 --- a/dom/script/ModuleScript.cpp +++ b/dom/script/ModuleScript.cpp @@ -21,7 +21,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleScript) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ModuleScript) NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader) NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL) - tmp->UnlinkModuleRecord(); + tmp->UnlinkScript(); tmp->mParseError.setUndefined(); tmp->mErrorToRethrow.setUndefined(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END @@ -31,7 +31,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ModuleScript) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ModuleScript) - NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRecord) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScript) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mParseError) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mErrorToRethrow) NS_IMPL_CYCLE_COLLECTION_TRACE_END @@ -46,42 +46,42 @@ ModuleScript::ModuleScript(ScriptLoader* aLoader, nsIURI* aBaseURL) { MOZ_ASSERT(mLoader); MOZ_ASSERT(mBaseURL); - MOZ_ASSERT(!mModuleRecord); + MOZ_ASSERT(!mScript); MOZ_ASSERT(!HasParseError()); MOZ_ASSERT(!HasErrorToRethrow()); } void -ModuleScript::UnlinkModuleRecord() +ModuleScript::UnlinkScript() { // Remove module's back reference to this object request if present. - if (mModuleRecord) { - MOZ_ASSERT(JS::GetModuleHostDefinedField(mModuleRecord).toPrivate() == + if (mScript) { + MOZ_ASSERT(JS::GetModuleHostDefinedField(mScript).toPrivate() == this); - JS::SetModuleHostDefinedField(mModuleRecord, JS::UndefinedValue()); - mModuleRecord = nullptr; + JS::SetModuleHostDefinedField(mScript, JS::UndefinedValue()); + mScript = nullptr; } } ModuleScript::~ModuleScript() { // The object may be destroyed without being unlinked first. - UnlinkModuleRecord(); + UnlinkScript(); DropJSObjects(this); } void -ModuleScript::SetModuleRecord(JS::Handle aModuleRecord) +ModuleScript::SetScript(JS::Handle aScript) { - MOZ_ASSERT(!mModuleRecord); + MOZ_ASSERT(!mScript); MOZ_ASSERT(!HasParseError()); MOZ_ASSERT(!HasErrorToRethrow()); - mModuleRecord = aModuleRecord; + mScript = aScript; // Make module's host defined field point to this module script object. - // This is cleared in the UnlinkModuleRecord(). - JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this)); + // This is cleared in the UnlinkScript(). + JS::SetModuleHostDefinedField(mScript, JS::PrivateValue(this)); HoldJSObjects(this); } @@ -92,7 +92,7 @@ ModuleScript::SetParseError(const JS::Value& aError) MOZ_ASSERT(!HasParseError()); MOZ_ASSERT(!HasErrorToRethrow()); - UnlinkModuleRecord(); + UnlinkScript(); mParseError = aError; HoldJSObjects(this); } @@ -103,9 +103,9 @@ ModuleScript::SetErrorToRethrow(const JS::Value& aError) MOZ_ASSERT(!aError.isUndefined()); MOZ_ASSERT(!HasErrorToRethrow()); - // This is only called after SetModuleRecord() or SetParseError() so we don't + // This is only called after SetScript() or SetParseError() so we don't // need to call HoldJSObjects() here. - MOZ_ASSERT(mModuleRecord || HasParseError()); + MOZ_ASSERT(mScript || HasParseError()); mErrorToRethrow = aError; } @@ -113,7 +113,7 @@ ModuleScript::SetErrorToRethrow(const JS::Value& aError) void ModuleScript::SetSourceElementAssociated() { - MOZ_ASSERT(mModuleRecord); + MOZ_ASSERT(mScript); MOZ_ASSERT(!mSourceElementAssociated); mSourceElementAssociated = true; diff --git a/dom/script/ModuleScript.h b/dom/script/ModuleScript.h index bb5d4117da82..dffa3173e5e5 100644 --- a/dom/script/ModuleScript.h +++ b/dom/script/ModuleScript.h @@ -22,7 +22,7 @@ class ModuleScript final : public nsISupports { RefPtr mLoader; nsCOMPtr mBaseURL; - JS::Heap mModuleRecord; + JS::Heap mScript; JS::Heap mParseError; JS::Heap mErrorToRethrow; bool mSourceElementAssociated; @@ -36,13 +36,13 @@ public: ModuleScript(ScriptLoader* aLoader, nsIURI* aBaseURL); - void SetModuleRecord(JS::Handle aModuleRecord); + void SetScript(JS::Handle aScript); void SetParseError(const JS::Value& aError); void SetErrorToRethrow(const JS::Value& aError); void SetSourceElementAssociated(); ScriptLoader* Loader() const { return mLoader; } - JSObject* ModuleRecord() const { return mModuleRecord; } + JSScript* Script() const { return mScript; } nsIURI* BaseURL() const { return mBaseURL; } JS::Value ParseError() const { return mParseError; } JS::Value ErrorToRethrow() const { return mErrorToRethrow; } @@ -50,7 +50,7 @@ public: bool HasErrorToRethrow() const { return !mErrorToRethrow.isUndefined(); } bool SourceElementAssociated() const { return mSourceElementAssociated; } - void UnlinkModuleRecord(); + void UnlinkScript(); }; } // dom namespace diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index a4c6ac681402..1cb8bc6b1b43 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -478,12 +478,12 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) nsresult rv; { JSContext* cx = aes.cx(); - JS::Rooted module(cx); + JS::Rooted script(cx); if (aRequest->mWasCompiledOMT) { - module = JS::FinishOffThreadModule(cx, aRequest->mOffThreadToken); + script = JS::FinishOffThreadModule(cx, aRequest->mOffThreadToken); aRequest->mOffThreadToken = nullptr; - rv = module ? NS_OK : NS_ERROR_FAILURE; + rv = script ? NS_OK : NS_ERROR_FAILURE; } else { JS::Rooted global(cx, globalObject->GetGlobalJSObject()); @@ -493,19 +493,19 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) if (NS_SUCCEEDED(rv)) { auto srcBuf = GetScriptSource(cx, aRequest); if (srcBuf) { - rv = nsJSUtils::CompileModule(cx, *srcBuf, global, options, &module); + rv = nsJSUtils::CompileModule(cx, *srcBuf, global, options, &script); } else { rv = NS_ERROR_OUT_OF_MEMORY; } } } - MOZ_ASSERT(NS_SUCCEEDED(rv) == (module != nullptr)); + MOZ_ASSERT(NS_SUCCEEDED(rv) == (script != nullptr)); RefPtr moduleScript = new ModuleScript(this, aRequest->mBaseURL); aRequest->mModuleScript = moduleScript; - if (!module) { + if (!script) { LOG(("ScriptLoadRequest (%p): compilation failed (%d)", aRequest, unsigned(rv))); @@ -521,7 +521,7 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) return NS_OK; } - moduleScript->SetModuleRecord(module); + moduleScript->SetScript(script); // Validate requested modules and treat failure to resolve module specifiers // the same as a parse error. @@ -614,14 +614,14 @@ ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray* aUrlsOu ModuleScript* ms = aRequest->mModuleScript; AutoJSAPI jsapi; - if (!jsapi.Init(ms->ModuleRecord())) { + if (!jsapi.Init(JS::GetScriptGlobal(ms->Script()))) { return NS_ERROR_FAILURE; } JSContext* cx = jsapi.cx(); - JS::Rooted moduleRecord(cx, ms->ModuleRecord()); + JS::Rooted script(cx, ms->Script()); JS::Rooted requestedModules(cx); - requestedModules = JS::GetRequestedModules(cx, moduleRecord); + requestedModules = JS::GetRequestedModules(cx, script); MOZ_ASSERT(requestedModules); uint32_t length; @@ -755,14 +755,14 @@ ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent, } // 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier) -JSObject* -HostResolveImportedModule(JSContext* aCx, JS::Handle aModule, +JSScript* +HostResolveImportedModule(JSContext* aCx, JS::Handle aScript, JS::Handle aSpecifier) { // Let referencing module script be referencingModule.[[HostDefined]]. - JS::Value value = JS::GetModuleHostDefinedField(aModule); + JS::Value value = JS::GetModuleHostDefinedField(aScript); auto script = static_cast(value.toPrivate()); - MOZ_ASSERT(script->ModuleRecord() == aModule); + MOZ_ASSERT(script->Script() == aScript); // Let url be the result of resolving a module specifier given referencing // module script and specifier. @@ -783,25 +783,25 @@ HostResolveImportedModule(JSContext* aCx, JS::Handle aModule, MOZ_ASSERT(ms, "Resolved module not found in module map"); MOZ_ASSERT(!ms->HasParseError()); - MOZ_ASSERT(ms->ModuleRecord()); + MOZ_ASSERT(ms->Script()); - return ms->ModuleRecord(); + return ms->Script(); } bool -HostPopulateImportMeta(JSContext* aCx, JS::Handle aModule, +HostPopulateImportMeta(JSContext* aCx, JS::Handle aScript, JS::Handle aMetaObject) { - MOZ_DIAGNOSTIC_ASSERT(aModule); + MOZ_DIAGNOSTIC_ASSERT(aScript); - JS::Value value = JS::GetModuleHostDefinedField(aModule); + JS::Value value = JS::GetModuleHostDefinedField(aScript); if (value.isUndefined()) { JS_ReportErrorASCII(aCx, "Module script not found"); return false; } auto script = static_cast(value.toPrivate()); - MOZ_DIAGNOSTIC_ASSERT(script->ModuleRecord() == aModule); + MOZ_DIAGNOSTIC_ASSERT(script->Script() == aScript); nsAutoCString url; MOZ_DIAGNOSTIC_ASSERT(script->BaseURL()); @@ -932,18 +932,18 @@ ScriptLoader::InstantiateModuleTree(ModuleLoadRequest* aRequest) return true; } - MOZ_ASSERT(moduleScript->ModuleRecord()); + MOZ_ASSERT(moduleScript->Script()); nsAutoMicroTask mt; AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(moduleScript->ModuleRecord()))) { + if (NS_WARN_IF(!jsapi.Init(JS::GetScriptGlobal(moduleScript->Script())))) { return false; } EnsureModuleResolveHook(jsapi.cx()); - JS::Rooted module(jsapi.cx(), moduleScript->ModuleRecord()); - bool ok = NS_SUCCEEDED(nsJSUtils::ModuleInstantiate(jsapi.cx(), module)); + JS::Rooted script(jsapi.cx(), moduleScript->Script()); + bool ok = NS_SUCCEEDED(nsJSUtils::ModuleInstantiate(jsapi.cx(), script)); if (!ok) { LOG(("ScriptLoadRequest (%p): Instantiate failed", aRequest)); @@ -2303,20 +2303,19 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) return NS_OK; // An error is reported by AutoEntryScript. } - JS::Rooted module(cx, moduleScript->ModuleRecord()); - MOZ_ASSERT(module); + JS::Rooted script(cx, moduleScript->Script()); + MOZ_ASSERT(script); if (!moduleScript->SourceElementAssociated()) { - rv = nsJSUtils::InitModuleSourceElement(cx, module, aRequest->Element()); + rv = nsJSUtils::InitModuleSourceElement(cx, script, aRequest->Element()); NS_ENSURE_SUCCESS(rv, rv); moduleScript->SetSourceElementAssociated(); // The script is now ready to be exposed to the debugger. - JS::Rooted script(cx, JS::GetModuleScript(module)); JS::ExposeScriptToDebugger(cx, script); } - rv = nsJSUtils::ModuleEvaluate(cx, module); + rv = nsJSUtils::ModuleEvaluate(cx, script); MOZ_ASSERT(NS_FAILED(rv) == aes.HasException()); if (NS_FAILED(rv)) { LOG(("ScriptLoadRequest (%p): evaluation failed", aRequest)); diff --git a/dom/script/ScriptLoader.h b/dom/script/ScriptLoader.h index 50b37468893e..d1189ced936a 100644 --- a/dom/script/ScriptLoader.h +++ b/dom/script/ScriptLoader.h @@ -520,8 +520,8 @@ private: RefPtr WaitForModuleFetch(nsIURI* aURL); ModuleScript* GetFetchedModule(nsIURI* aURL) const; - friend JSObject* - HostResolveImportedModule(JSContext* aCx, JS::Handle aModule, + friend JSScript* + HostResolveImportedModule(JSContext* aCx, JS::Handle aScript, JS::Handle aSpecifier); // Returns wether we should save the bytecode of this script after the diff --git a/js/public/Realm.h b/js/public/Realm.h index 719adbc2f5bb..1e8f00481c0d 100644 --- a/js/public/Realm.h +++ b/js/public/Realm.h @@ -73,6 +73,11 @@ GetCompartmentForRealm(Realm* realm) extern JS_PUBLIC_API(Realm*) GetObjectRealmOrNull(JSObject* obj); +// Return a script's realm. All scripts are created in a particular realm, which +// never changes. +extern JS_PUBLIC_API(Realm*) +GetScriptRealm(JSScript* script); + // Get the value of the "private data" internal field of the given Realm. // This field is initially null and is set using SetRealmPrivate. // It's a pointer to embeddding-specific data that SpiderMonkey never uses. diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index b5349aefb618..ece71b2860ed 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -1643,9 +1643,10 @@ ArrayObject* ModuleBuilder::createArray(const JS::Rooted>& map) } JSObject* -js::GetOrCreateModuleMetaObject(JSContext* cx, HandleObject moduleArg) +js::GetOrCreateModuleMetaObject(JSContext* cx, HandleScript script) { - HandleModuleObject module = moduleArg.as(); + MOZ_ASSERT(script->module()); + RootedModuleObject module(cx, script->module()); if (JSObject* obj = module->metaObject()) return obj; @@ -1659,7 +1660,7 @@ js::GetOrCreateModuleMetaObject(JSContext* cx, HandleObject moduleArg) return nullptr; } - if (!func(cx, module, metaObject)) + if (!func(cx, script, metaObject)) return nullptr; module->setMetaObject(metaObject); diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h index 8bc625729fc3..9216acbc7111 100644 --- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -412,7 +412,7 @@ class MOZ_STACK_CLASS ModuleBuilder }; JSObject* -GetOrCreateModuleMetaObject(JSContext* cx, HandleObject module); +GetOrCreateModuleMetaObject(JSContext* cx, HandleScript script); } // namespace js diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 73529af9f0eb..824128e00fc2 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -47,7 +47,7 @@ class MOZ_STACK_CLASS BytecodeCompiler JSScript* compileGlobalScript(ScopeKind scopeKind); JSScript* compileEvalScript(HandleObject environment, HandleScope enclosingScope); - ModuleObject* compileModule(); + JSScript* compileModule(); bool compileStandaloneFunction(MutableHandleFunction fun, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, const Maybe& parameterListEnd); @@ -394,7 +394,7 @@ BytecodeCompiler::compileEvalScript(HandleObject environment, HandleScope enclos return compileScript(environment, &evalsc); } -ModuleObject* +JSScript* BytecodeCompiler::compileModule() { if (!createSourceAndParser(ParseGoal::Module)) @@ -438,7 +438,7 @@ BytecodeCompiler::compileModule() return nullptr; MOZ_ASSERT_IF(!cx->helperThread(), !cx->isExceptionPending()); - return module; + return script; } // Compile a standalone JS function, which might appear as the value of an @@ -687,7 +687,7 @@ frontend::CompileEvalScript(JSContext* cx, LifoAlloc& alloc, } -ModuleObject* +JSScript* frontend::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& optionsInput, SourceBufferHolder& srcBuf, LifoAlloc& alloc, ScriptSourceObject** sourceObjectOut) @@ -705,15 +705,15 @@ frontend::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& optionsInpu RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope()); BytecodeCompiler compiler(cx, alloc, options, srcBuf, emptyGlobalScope); AutoInitializeSourceObject autoSSO(compiler, sourceObjectOut); - ModuleObject* module = compiler.compileModule(); - if (!module) + JSScript* script = compiler.compileModule(); + if (!script) return nullptr; assertException.reset(); - return module; + return script; } -ModuleObject* +JSScript* frontend::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, SourceBufferHolder& srcBuf) { @@ -723,17 +723,18 @@ frontend::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, return nullptr; LifoAlloc& alloc = cx->tempLifoAlloc(); - RootedModuleObject module(cx, CompileModule(cx, options, srcBuf, alloc)); - if (!module) + RootedScript script(cx, CompileModule(cx, options, srcBuf, alloc)); + if (!script) return nullptr; // This happens in GlobalHelperThreadState::finishModuleParseTask() when a // module is compiled off thread. + RootedModuleObject module(cx, script->module()); if (!ModuleObject::Freeze(cx, module)) return nullptr; assertException.reset(); - return module; + return script; } // When leaving this scope, the given function should either: diff --git a/js/src/frontend/BytecodeCompiler.h b/js/src/frontend/BytecodeCompiler.h index 84209b7c1b7a..16943f9047b2 100644 --- a/js/src/frontend/BytecodeCompiler.h +++ b/js/src/frontend/BytecodeCompiler.h @@ -21,7 +21,6 @@ namespace js { class LazyScript; class LifoAlloc; -class ModuleObject; class ScriptSourceObject; namespace frontend { @@ -53,11 +52,11 @@ CompileEvalScript(JSContext* cx, LifoAlloc& alloc, SourceBufferHolder& srcBuf, ScriptSourceObject** sourceObjectOut = nullptr); -ModuleObject* +JSScript* CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, SourceBufferHolder& srcBuf); -ModuleObject* +JSScript* CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, SourceBufferHolder& srcBuf, LifoAlloc& alloc, ScriptSourceObject** sourceObjectOut = nullptr); diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index a39000fff8ff..6fc9be48c4aa 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -5138,7 +5138,8 @@ BaselineCompiler::emit_JSOP_IMPORTMETA() RootedModuleObject module(cx, GetModuleObjectForScript(script)); MOZ_ASSERT(module); - JSObject* metaObject = GetOrCreateModuleMetaObject(cx, module); + RootedScript moduleScript(cx, module->script()); + JSObject* metaObject = GetOrCreateModuleMetaObject(cx, moduleScript); if (!metaObject) return false; diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index d5fc751c5ee1..5ee3e1706708 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1271,6 +1271,15 @@ JS::GetNonCCWObjectGlobal(JSObject* obj) return &obj->nonCCWGlobal(); } +JS_PUBLIC_API(JSObject*) +JS::GetScriptGlobal(JSScript* script) +{ + AssertHeapIsIdleOrIterating(); + JSObject* global = script->realm()->maybeGlobal(); + MOZ_ASSERT(global); + return global; +} + JS_PUBLIC_API(bool) JS::detail::ComputeThis(JSContext* cx, Value* vp, MutableHandleObject thisObject) { @@ -4247,7 +4256,7 @@ JS::CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options, return StartOffThreadParseModule(cx, options, srcBuf, callback, callbackData); } -JS_PUBLIC_API(JSObject*) +JS_PUBLIC_API(JSScript*) JS::FinishOffThreadModule(JSContext* cx, JS::OffThreadToken* token) { MOZ_ASSERT(cx); @@ -4838,53 +4847,61 @@ JS::SetModuleMetadataHook(JSRuntime* rt, JS::ModuleMetadataHook func) JS_PUBLIC_API(bool) JS::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleObject module) + SourceBufferHolder& srcBuf, JS::MutableHandleScript script) { MOZ_ASSERT(!cx->zone()->isAtomsZone()); AssertHeapIsIdle(); CHECK_REQUEST(cx); - module.set(frontend::CompileModule(cx, options, srcBuf)); - return !!module; + script.set(frontend::CompileModule(cx, options, srcBuf)); + return !!script; } JS_PUBLIC_API(void) -JS::SetModuleHostDefinedField(JSObject* module, const JS::Value& value) +JS::SetModuleHostDefinedField(JSScript* script, const JS::Value& value) { - module->as().setHostDefinedField(value); + MOZ_ASSERT(script->module()); + script->module()->setHostDefinedField(value); } JS_PUBLIC_API(JS::Value) -JS::GetModuleHostDefinedField(JSObject* module) +JS::GetModuleHostDefinedField(JSScript* script) { - return module->as().hostDefinedField(); + MOZ_ASSERT(script->module()); + return script->module()->hostDefinedField(); } JS_PUBLIC_API(bool) -JS::ModuleInstantiate(JSContext* cx, JS::HandleObject moduleArg) +JS::ModuleInstantiate(JSContext* cx, JS::HandleScript script) { AssertHeapIsIdle(); CHECK_REQUEST(cx); - assertSameCompartment(cx, moduleArg); - return ModuleObject::Instantiate(cx, moduleArg.as()); + assertSameCompartment(cx, script); + RootedModuleObject module(cx, script->module()); + MOZ_ASSERT(module); + return ModuleObject::Instantiate(cx, module); } JS_PUBLIC_API(bool) -JS::ModuleEvaluate(JSContext* cx, JS::HandleObject moduleArg) +JS::ModuleEvaluate(JSContext* cx, JS::HandleScript script) { AssertHeapIsIdle(); CHECK_REQUEST(cx); - assertSameCompartment(cx, moduleArg); - return ModuleObject::Evaluate(cx, moduleArg.as()); + assertSameCompartment(cx, script); + RootedModuleObject module(cx, script->module()); + MOZ_ASSERT(module); + return ModuleObject::Evaluate(cx, module); } JS_PUBLIC_API(JSObject*) -JS::GetRequestedModules(JSContext* cx, JS::HandleObject moduleArg) +JS::GetRequestedModules(JSContext* cx, JS::HandleScript script) { AssertHeapIsIdle(); CHECK_REQUEST(cx); - assertSameCompartment(cx, moduleArg); - return &moduleArg->as().requestedModules(); + assertSameCompartment(cx, script); + RootedModuleObject module(cx, script->module()); + MOZ_ASSERT(module); + return &module->requestedModules(); } JS_PUBLIC_API(JSString*) @@ -4911,13 +4928,6 @@ JS::GetRequestedModuleSourcePos(JSContext* cx, JS::HandleValue value, *columnNumber = requested.columnNumber(); } -JS_PUBLIC_API(JSScript*) -JS::GetModuleScript(JS::HandleObject moduleRecord) -{ - AssertHeapIsIdle(); - return moduleRecord->as().script(); -} - JS_PUBLIC_API(JSObject*) JS_New(JSContext* cx, HandleObject ctor, const JS::HandleValueArray& inputArgs) { diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 99b24245bf71..8fd693cd0afe 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1234,6 +1234,12 @@ CurrentGlobalOrNull(JSContext* cx); extern JS_PUBLIC_API(JSObject*) GetNonCCWObjectGlobal(JSObject* obj); +/** + * Get the global object associated with a script's realm. + */ +extern JS_PUBLIC_API(JSObject*) +GetScriptGlobal(JSScript* script); + } // namespace JS /** @@ -3692,7 +3698,7 @@ CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, OffThreadCompileCallback callback, void* callbackData); -extern JS_PUBLIC_API(JSObject*) +extern JS_PUBLIC_API(JSScript*) FinishOffThreadModule(JSContext* cx, OffThreadToken* token); extern JS_PUBLIC_API(void) @@ -3864,7 +3870,7 @@ extern JS_PUBLIC_API(bool) Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, const char* filename, JS::MutableHandleValue rval); -using ModuleResolveHook = JSObject* (*)(JSContext*, HandleObject, HandleString); +using ModuleResolveHook = JSScript* (*)(JSContext*, HandleScript, HandleString); /** * Get the HostResolveImportedModule hook for the runtime. @@ -3878,7 +3884,7 @@ GetModuleResolveHook(JSRuntime* rt); extern JS_PUBLIC_API(void) SetModuleResolveHook(JSRuntime* rt, ModuleResolveHook func); -using ModuleMetadataHook = bool (*)(JSContext*, HandleObject, HandleObject); +using ModuleMetadataHook = bool (*)(JSContext*, HandleScript, HandleObject); /** * Get the hook for populating the import.meta metadata object. @@ -3895,24 +3901,24 @@ SetModuleMetadataHook(JSRuntime* rt, ModuleMetadataHook func); /** * Parse the given source buffer as a module in the scope of the current global - * of cx and return a source text module record. + * of cx. */ extern JS_PUBLIC_API(bool) CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord); + SourceBufferHolder& srcBuf, JS::MutableHandleScript script); /** * Set the [[HostDefined]] field of a source text module record to the given * value. */ extern JS_PUBLIC_API(void) -SetModuleHostDefinedField(JSObject* module, const JS::Value& value); +SetModuleHostDefinedField(JSScript* module, const JS::Value& value); /** * Get the [[HostDefined]] field of a source text module record. */ extern JS_PUBLIC_API(JS::Value) -GetModuleHostDefinedField(JSObject* module); +GetModuleHostDefinedField(JSScript* script); /* * Perform the ModuleInstantiate operation on the given source text module @@ -3923,7 +3929,7 @@ GetModuleHostDefinedField(JSObject* module); * the module. */ extern JS_PUBLIC_API(bool) -ModuleInstantiate(JSContext* cx, JS::HandleObject moduleRecord); +ModuleInstantiate(JSContext* cx, JS::HandleScript script); /* * Perform the ModuleEvaluate operation on the given source text module record. @@ -3935,7 +3941,7 @@ ModuleInstantiate(JSContext* cx, JS::HandleObject moduleRecord); * ModuleInstantiate must have completed prior to calling this. */ extern JS_PUBLIC_API(bool) -ModuleEvaluate(JSContext* cx, JS::HandleObject moduleRecord); +ModuleEvaluate(JSContext* cx, JS::HandleScript script); /* * Get a list of the module specifiers used by a source text module @@ -3954,7 +3960,7 @@ ModuleEvaluate(JSContext* cx, JS::HandleObject moduleRecord); * GetRequestedModuleSourcePos() */ extern JS_PUBLIC_API(JSObject*) -GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord); +GetRequestedModules(JSContext* cx, JS::HandleScript script); extern JS_PUBLIC_API(JSString*) GetRequestedModuleSpecifier(JSContext* cx, JS::HandleValue requestedModuleObject); @@ -3963,9 +3969,6 @@ extern JS_PUBLIC_API(void) GetRequestedModuleSourcePos(JSContext* cx, JS::HandleValue requestedModuleObject, uint32_t* lineNumber, uint32_t* columnNumber); -extern JS_PUBLIC_API(JSScript*) -GetModuleScript(JS::HandleObject moduleRecord); - } /* namespace JS */ #if defined(JS_BUILD_BINAST) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 7e4e6f478e40..bdb3d7daa7e3 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -4299,11 +4299,11 @@ ParseModule(JSContext* cx, unsigned argc, Value* vp) SourceBufferHolder srcBuf(chars, scriptContents->length(), SourceBufferHolder::NoOwnership); - RootedObject module(cx, frontend::CompileModule(cx, options, srcBuf)); - if (!module) + RootedScript script(cx, frontend::CompileModule(cx, options, srcBuf)); + if (!script) return false; - args.rval().setObject(*module); + args.rval().setObject(*script->module()); return true; } @@ -4330,9 +4330,11 @@ SetModuleResolveHook(JSContext* cx, unsigned argc, Value* vp) return true; } -static JSObject* -CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier) +static JSScript* +CallModuleResolveHook(JSContext* cx, HandleScript script, HandleString specifier) { + MOZ_ASSERT(script->module()); + Handle global = cx->global(); RootedValue hookValue(cx, global->getReservedSlot(GlobalAppSlotModuleResolveHook)); if (hookValue.isUndefined()) { @@ -4342,7 +4344,7 @@ CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier MOZ_ASSERT(hookValue.toObject().is()); JS::AutoValueArray<2> args(cx); - args[0].setObject(*module); + args[0].setObject(*script->module()); args[1].setString(specifier); RootedValue result(cx); @@ -4354,14 +4356,13 @@ CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier return nullptr; } - return &result.toObject(); + return result.toObject().as().script(); } static bool -ShellModuleMetadataHook(JSContext* cx, HandleObject module, HandleObject metaObject) +ShellModuleMetadataHook(JSContext* cx, HandleScript script, HandleObject metaObject) { // For the shell, just use the script's filename as the base URL. - RootedScript script(cx, module->as().script()); const char* filename = script->scriptSource()->filename(); MOZ_ASSERT(filename); @@ -4863,11 +4864,11 @@ FinishOffThreadModule(JSContext* cx, unsigned argc, Value* vp) DeleteOffThreadJob(cx, job); - RootedObject module(cx, JS::FinishOffThreadModule(cx, token)); - if (!module) + RootedScript script(cx, JS::FinishOffThreadModule(cx, token)); + if (!script) return false; - args.rval().setObject(*module); + args.rval().setObject(*script->module()); return true; } diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index c25136b0fd89..e817db9908ab 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -525,9 +525,9 @@ ModuleParseTask::parse(JSContext* cx) { Rooted sourceObject(cx); - ModuleObject* module = frontend::CompileModule(cx, options, data, alloc, &sourceObject.get()); - if (module) { - scripts.infallibleAppend(module->script()); + JSScript* script = frontend::CompileModule(cx, options, data, alloc, &sourceObject.get()); + if (script) { + scripts.infallibleAppend(script); if (sourceObject) sourceObjects.infallibleAppend(sourceObject); } @@ -1806,10 +1806,10 @@ GlobalHelperThreadState::finishMultiScriptsDecodeTask(JSContext* cx, JS::OffThre return finishParseTask(cx, ParseTaskKind::MultiScriptsDecode, token, scripts); } -JSObject* +JSScript* GlobalHelperThreadState::finishModuleParseTask(JSContext* cx, JS::OffThreadToken* token) { - JSScript* script = finishParseTask(cx, ParseTaskKind::Module, token); + RootedScript script(cx, finishParseTask(cx, ParseTaskKind::Module, token)); if (!script) return nullptr; @@ -1820,7 +1820,7 @@ GlobalHelperThreadState::finishModuleParseTask(JSContext* cx, JS::OffThreadToken if (!ModuleObject::Freeze(cx, module)) return nullptr; - return module; + return script; } void diff --git a/js/src/vm/HelperThreads.h b/js/src/vm/HelperThreads.h index c9733be16caf..f0bd0124945c 100644 --- a/js/src/vm/HelperThreads.h +++ b/js/src/vm/HelperThreads.h @@ -306,7 +306,7 @@ class GlobalHelperThreadState JSScript* finishScriptParseTask(JSContext* cx, JS::OffThreadToken* token); JSScript* finishScriptDecodeTask(JSContext* cx, JS::OffThreadToken* token); bool finishMultiScriptsDecodeTask(JSContext* cx, JS::OffThreadToken* token, MutableHandle scripts); - JSObject* finishModuleParseTask(JSContext* cx, JS::OffThreadToken* token); + JSScript* finishModuleParseTask(JSContext* cx, JS::OffThreadToken* token); #if defined(JS_BUILD_BINAST) JSScript* finishBinASTDecodeTask(JSContext* cx, JS::OffThreadToken* token); diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 876f748fe414..8686dde3237c 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -4403,7 +4403,8 @@ CASE(JSOP_IMPORTMETA) ReservedRooted module(&rootObject0, GetModuleObjectForScript(script)); MOZ_ASSERT(module); - JSObject* metaObject = GetOrCreateModuleMetaObject(cx, module); + ReservedRooted script(&rootScript0, module->as().script()); + JSObject* metaObject = GetOrCreateModuleMetaObject(cx, script); if (!metaObject) goto error; diff --git a/js/src/vm/Realm.cpp b/js/src/vm/Realm.cpp index 80272d78398d..98a795f831ca 100644 --- a/js/src/vm/Realm.cpp +++ b/js/src/vm/Realm.cpp @@ -1021,6 +1021,12 @@ JS::GetObjectRealmOrNull(JSObject* obj) return IsCrossCompartmentWrapper(obj) ? nullptr : obj->nonCCWRealm(); } +JS_PUBLIC_API(JS::Realm*) +JS::GetScriptRealm(JSScript* script) +{ + return script->realm(); +} + JS_PUBLIC_API(void*) JS::GetRealmPrivate(JS::Realm* realm) { diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index e57e1885c38d..df4650e2c7f7 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -2151,17 +2151,18 @@ intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp) return false; } - RootedObject result(cx); - result = moduleResolveHook(cx, module, specifier); + RootedScript script(cx, module->script()); + RootedScript result(cx); + result = moduleResolveHook(cx, script, specifier); if (!result) return false; - if (!result->is()) { - JS_ReportErrorASCII(cx, "Module resolve hook did not return Module object"); + if (!result->module()) { + JS_ReportErrorASCII(cx, "Module resolve hook did not return a module script"); return false; } - args.rval().setObject(*result); + args.rval().setObject(*result->module()); return true; } diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 5b6e04d24cbd..8fe40cecbfb1 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -441,6 +441,13 @@ Scriptability::Get(JSObject* aScope) return RealmPrivate::Get(aScope)->scriptability; } +/* static */ +Scriptability& +Scriptability::Get(JSScript* aScript) +{ + return RealmPrivate::Get(aScript)->scriptability; +} + bool IsContentXBLCompartment(JS::Compartment* compartment) { diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 582c9af50905..f25ffd6f4f2b 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -2991,6 +2991,13 @@ public: return Get(realm); } + // Get the RealmPrivate for a given script. + static RealmPrivate* Get(JSScript* script) + { + JS::Realm* realm = JS::GetScriptRealm(script); + return Get(realm); + } + // The scriptability of this realm. Scriptability scriptability; diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index 08fdffed4bdf..effad1d417b5 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -54,6 +54,7 @@ public: void SetDocShellAllowsScript(bool aAllowed); static Scriptability& Get(JSObject* aScope); + static Scriptability& Get(JSScript* aScript); private: // Whenever a consumer wishes to prevent script from running on a global,