Bug 1342012 - Support dynamic import from classic scripts by creating ClassicScript objects and associating them with the compiled JSScriptsr r=smaug

This commit is contained in:
Jon Coppeard 2018-12-06 16:52:17 -05:00
Родитель e6bd951e8e
Коммит 142826e981
13 изменённых файлов: 74 добавлений и 75 удалений

Просмотреть файл

@ -53,6 +53,33 @@ LoadedScript::LoadedScript(ScriptKind aKind, ScriptLoader* aLoader,
LoadedScript::~LoadedScript() { DropJSObjects(this); } LoadedScript::~LoadedScript() { DropJSObjects(this); }
void LoadedScript::AssociateWithScript(JSScript* aScript) {
// Set a JSScript's private value to point to this object and
// increment our reference count. This is decremented by
// HostFinalizeTopLevelScript() below when the JSScript dies.
MOZ_ASSERT(JS::GetScriptPrivate(aScript).isUndefined());
JS::SetScriptPrivate(aScript, JS::PrivateValue(this));
AddRef();
}
void HostFinalizeTopLevelScript(JSFreeOp* aFop, const JS::Value& aPrivate) {
// Decrement the reference count of a LoadedScript object that is
// pointed to by a dying JSScript. The reference count was
// originally incremented by AssociateWithScript() above.
auto script = static_cast<LoadedScript*>(aPrivate.toPrivate());
#ifdef DEBUG
if (script->IsModuleScript()) {
JSObject* module = script->AsModuleScript()->mModuleRecord.unbarrieredGet();
MOZ_ASSERT(JS::GetModulePrivate(module) == aPrivate);
}
#endif
script->Release();
}
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// ClassicScript // ClassicScript
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
@ -132,15 +159,6 @@ void ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord) {
AddRef(); AddRef();
} }
void HostFinalizeTopLevelScript(JSFreeOp* aFop, const JS::Value& aPrivate) {
auto script = static_cast<ModuleScript*>(aPrivate.toPrivate());
if (script) {
MOZ_ASSERT(JS::GetModulePrivate(script->mModuleRecord.unbarrieredGet()) ==
aPrivate);
script->UnlinkModuleRecord();
}
}
void ModuleScript::SetParseError(const JS::Value& aError) { void ModuleScript::SetParseError(const JS::Value& aError) {
MOZ_ASSERT(!aError.isUndefined()); MOZ_ASSERT(!aError.isUndefined());
MOZ_ASSERT(!HasParseError()); MOZ_ASSERT(!HasParseError());

Просмотреть файл

@ -48,6 +48,8 @@ class LoadedScript : public nsISupports {
ScriptLoader* Loader() const { return mLoader; } ScriptLoader* Loader() const { return mLoader; }
ScriptFetchOptions* FetchOptions() const { return mFetchOptions; } ScriptFetchOptions* FetchOptions() const { return mFetchOptions; }
nsIURI* BaseURL() const { return mBaseURL; } nsIURI* BaseURL() const { return mBaseURL; }
void AssociateWithScript(JSScript* aScript);
}; };
class ClassicScript final : public LoadedScript { class ClassicScript final : public LoadedScript {

Просмотреть файл

@ -25,13 +25,13 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleLoadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleLoadRequest, NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleLoadRequest,
ScriptLoadRequest) ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL, mLoader, mModuleScript, mImports) NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader, mModuleScript, mImports)
tmp->ClearDynamicImport(); tmp->ClearDynamicImport();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleLoadRequest, NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleLoadRequest,
ScriptLoadRequest) ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBaseURL, mLoader, mModuleScript, mImports) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader, mModuleScript, mImports)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleLoadRequest, NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleLoadRequest,
@ -74,7 +74,7 @@ static VisitedURLSet* NewVisitedSetForTopLevelImport(nsIURI* aURI) {
} }
/* static */ ModuleLoadRequest* ModuleLoadRequest::CreateDynamicImport( /* static */ ModuleLoadRequest* ModuleLoadRequest::CreateDynamicImport(
nsIURI* aURI, ModuleScript* aScript, nsIURI* aURI, LoadedScript* aScript,
JS::Handle<JS::Value> aReferencingPrivate, JS::Handle<JSString*> aSpecifier, JS::Handle<JS::Value> aReferencingPrivate, JS::Handle<JSString*> aSpecifier,
JS::Handle<JSObject*> aPromise) { JS::Handle<JSObject*> aPromise) {
MOZ_ASSERT(aSpecifier); MOZ_ASSERT(aSpecifier);

Просмотреть файл

@ -59,7 +59,7 @@ class ModuleLoadRequest final : public ScriptLoadRequest {
// Create a module load request for dynamic module import. // Create a module load request for dynamic module import.
static ModuleLoadRequest* CreateDynamicImport( static ModuleLoadRequest* CreateDynamicImport(
nsIURI* aURI, ModuleScript* aScript, nsIURI* aURI, LoadedScript* aScript,
JS::Handle<JS::Value> aReferencingPrivate, JS::Handle<JS::Value> aReferencingPrivate,
JS::Handle<JSString*> aSpecifier, JS::Handle<JSObject*> aPromise); JS::Handle<JSString*> aSpecifier, JS::Handle<JSObject*> aPromise);
@ -87,9 +87,6 @@ class ModuleLoadRequest final : public ScriptLoadRequest {
// Is this the top level request for a dynamic module import? // Is this the top level request for a dynamic module import?
const bool mIsDynamicImport; const bool mIsDynamicImport;
// The base URL used for resolving relative module imports.
nsCOMPtr<nsIURI> mBaseURL;
// Pointer to the script loader, used to trigger actions when the module load // Pointer to the script loader, used to trigger actions when the module load
// finishes. // finishes.
RefPtr<ScriptLoader> mLoader; RefPtr<ScriptLoader> mLoader;

Просмотреть файл

@ -50,15 +50,13 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest) NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions) NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions, mCacheInfo)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheInfo)
tmp->mScript = nullptr; tmp->mScript = nullptr;
tmp->DropBytecodeCacheReferences(); tmp->DropBytecodeCacheReferences();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadRequest) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions, mCacheInfo)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheInfo)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ScriptLoadRequest) NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ScriptLoadRequest)

Просмотреть файл

@ -273,6 +273,9 @@ class ScriptLoadRequest
// Holds the Cache information, which is used to register the bytecode // Holds the Cache information, which is used to register the bytecode
// on the cache entry, such that we can load it the next time. // on the cache entry, such that we can load it the next time.
nsCOMPtr<nsICacheInfoChannel> mCacheInfo; nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
// The base URL used for resolving relative module imports.
nsCOMPtr<nsIURI> mBaseURL;
}; };
class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest> { class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest> {

Просмотреть файл

@ -547,7 +547,7 @@ static nsresult HandleResolveFailure(JSContext* aCx, ModuleScript* aScript,
} }
static already_AddRefed<nsIURI> ResolveModuleSpecifier( static already_AddRefed<nsIURI> ResolveModuleSpecifier(
ModuleScript* aScript, const nsAString& aSpecifier) { LoadedScript* aScript, const nsAString& aSpecifier) {
// The following module specifiers are allowed by the spec: // The following module specifiers are allowed by the spec:
// - a valid absolute URL // - a valid absolute URL
// - a valid relative URL that starts with "/", "./" or "../" // - a valid relative URL that starts with "/", "./" or "../"
@ -738,9 +738,12 @@ JSObject* HostResolveImportedModule(JSContext* aCx,
return nullptr; return nullptr;
} }
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate()); RefPtr<LoadedScript> script =
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) == static_cast<LoadedScript*>(aReferencingPrivate.toPrivate());
aReferencingPrivate); MOZ_ASSERT_IF(
script->IsModuleScript(),
JS::GetModulePrivate(script->AsModuleScript()->ModuleRecord()) ==
aReferencingPrivate);
// Let url be the result of resolving a module specifier given referencing // Let url be the result of resolving a module specifier given referencing
// module script and specifier. // module script and specifier.
@ -769,7 +772,9 @@ JSObject* HostResolveImportedModule(JSContext* aCx,
bool HostPopulateImportMeta(JSContext* aCx, bool HostPopulateImportMeta(JSContext* aCx,
JS::Handle<JS::Value> aReferencingPrivate, JS::Handle<JS::Value> aReferencingPrivate,
JS::Handle<JSObject*> aMetaObject) { JS::Handle<JSObject*> aMetaObject) {
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate()); RefPtr<ModuleScript> script =
static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
MOZ_ASSERT(script->IsModuleScript());
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) == MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) ==
aReferencingPrivate); aReferencingPrivate);
@ -797,9 +802,11 @@ bool HostImportModuleDynamically(JSContext* aCx,
return false; return false;
} }
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate()); auto script = static_cast<LoadedScript*>(aReferencingPrivate.toPrivate());
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) == MOZ_ASSERT_IF(
aReferencingPrivate); script->IsModuleScript(),
JS::GetModulePrivate(script->AsModuleScript()->ModuleRecord()) ==
aReferencingPrivate);
// Attempt to resolve the module specifier. // Attempt to resolve the module specifier.
nsAutoJSString string; nsAutoJSString string;
@ -1633,10 +1640,10 @@ bool ScriptLoader::ProcessInlineScript(nsIScriptElement* aElement,
LOG(("ScriptLoadRequest (%p): Created request for inline script", LOG(("ScriptLoadRequest (%p): Created request for inline script",
request.get())); request.get()));
request->mBaseURL = mDocument->GetDocBaseURI();
if (request->IsModuleRequest()) { if (request->IsModuleRequest()) {
ModuleLoadRequest* modReq = request->AsModuleRequest(); ModuleLoadRequest* modReq = request->AsModuleRequest();
modReq->mBaseURL = mDocument->GetDocBaseURI();
if (aElement->GetParserCreated() != NOT_FROM_PARSER) { if (aElement->GetParserCreated() != NOT_FROM_PARSER) {
if (aElement->GetScriptAsync()) { if (aElement->GetScriptAsync()) {
AddAsyncRequest(modReq); AddAsyncRequest(modReq);
@ -2523,6 +2530,13 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
if (rv == NS_OK) { if (rv == NS_OK) {
script = exec.GetScript(); script = exec.GetScript();
// Create a ClassicScript object and associate it with the
// JSScript.
RefPtr<ClassicScript> classicScript = new ClassicScript(
this, aRequest->mFetchOptions, aRequest->mBaseURL);
classicScript->AssociateWithScript(script);
rv = exec.ExecScript(); rv = exec.ExecScript();
} }
} }
@ -3301,6 +3315,18 @@ nsresult ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest,
mParserBlockingRequest == aRequest, mParserBlockingRequest == aRequest,
"aRequest should be pending!"); "aRequest should be pending!");
nsCOMPtr<nsIURI> uri;
rv = channel->GetOriginalURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
// Fixup moz-extension: and resource: URIs, because the channel URI will
// point to file:, which won't be allowed to load.
if (uri && IsInternalURIScheme(uri)) {
aRequest->mBaseURL = uri;
} else {
channel->GetURI(getter_AddRefs(aRequest->mBaseURL));
}
if (aRequest->IsModuleRequest()) { if (aRequest->IsModuleRequest()) {
MOZ_ASSERT(aRequest->IsSource()); MOZ_ASSERT(aRequest->IsSource());
ModuleLoadRequest* request = aRequest->AsModuleRequest(); ModuleLoadRequest* request = aRequest->AsModuleRequest();
@ -3314,18 +3340,6 @@ nsresult ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
nsCOMPtr<nsIURI> uri;
rv = channel->GetOriginalURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
// Fixup moz-extension: and resource: URIs, because the channel URI will
// point to file:, which won't be allowed to load.
if (uri && IsInternalURIScheme(uri)) {
request->mBaseURL = uri;
} else {
channel->GetURI(getter_AddRefs(request->mBaseURL));
}
// Attempt to compile off main thread. // Attempt to compile off main thread.
bool couldCompile = false; bool couldCompile = false;
rv = AttemptAsyncScriptCompile(request, &couldCompile); rv = AttemptAsyncScriptCompile(request, &couldCompile);

Просмотреть файл

@ -5,6 +5,3 @@
[propagate-nonce-external-classic] [propagate-nonce-external-classic]
expected: FAIL expected: FAIL
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
expected: FAIL

Просмотреть файл

@ -5,6 +5,3 @@
[propagate-nonce-inline-classic] [propagate-nonce-inline-classic]
expected: FAIL expected: FAIL
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
expected: FAIL

Просмотреть файл

@ -2,12 +2,6 @@
[setTimeout should successfully import] [setTimeout should successfully import]
expected: FAIL expected: FAIL
[eval should successfully import]
expected: FAIL
[Function should successfully import]
expected: FAIL
[reflected-inline-event-handlers should successfully import] [reflected-inline-event-handlers should successfully import]
expected: FAIL expected: FAIL

Просмотреть файл

@ -2,12 +2,6 @@
[setTimeout should successfully import] [setTimeout should successfully import]
expected: FAIL expected: FAIL
[eval should successfully import]
expected: FAIL
[the Function constructor should successfully import]
expected: FAIL
[reflected inline event handlers should successfully import] [reflected inline event handlers should successfully import]
expected: FAIL expected: FAIL

Просмотреть файл

@ -1,13 +1,7 @@
[string-compilation-classic.html] [string-compilation-classic.html]
[eval should successfully import]
expected: FAIL
[setTimeout should successfully import] [setTimeout should successfully import]
expected: FAIL expected: FAIL
[the Function constructor should successfully import]
expected: FAIL
[reflected inline event handlers should successfully import] [reflected inline event handlers should successfully import]
expected: FAIL expected: FAIL

Просмотреть файл

@ -2,15 +2,6 @@
[setTimeout must inherit the nonce from the triggering script, thus execute] [setTimeout must inherit the nonce from the triggering script, thus execute]
expected: FAIL expected: FAIL
[direct eval must inherit the nonce from the triggering script, thus execute]
expected: FAIL
[indirect eval must inherit the nonce from the triggering script, thus execute]
expected: FAIL
[the Function constructor must inherit the nonce from the triggering script, thus execute]
expected: FAIL
[reflected inline event handlers must inherit the nonce from the triggering script, thus execute] [reflected inline event handlers must inherit the nonce from the triggering script, thus execute]
expected: FAIL expected: FAIL