[JSC] ScriptFetcher should be notified directly from module pipeline
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Oct 2017 07:19:02 +0000 (07:19 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Oct 2017 07:19:02 +0000 (07:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178340

Reviewed by Sam Weinig.

Source/JavaScriptCore:

Previously, we use JSStdFunction to let WebCore inform the module pipeline results.
We setup JSStdFunction to the resulted promise of the module pipeline. It is super
ad-hoc since JSStdFunction's lambda need extra-careful to make it non-cyclic-referenced.
JSStdFunction's lambda can capture variables, but they are not able to be marked by GC.

But now, we have ScriptFetcher. It is introduced after we implemented the module pipeline
notification mechanism by using JSStdFunction. But it is appropriate one to receive notification
from the module pipeline by observer style.

This patch removes the above ad-hoc JSStdFunction use. And now ScriptFetcher receives
completion/failure notifications from the module pipeline.

* builtins/ModuleLoaderPrototype.js:
(loadModule):
(loadAndEvaluateModule):
* runtime/Completion.cpp:
(JSC::loadModule):
* runtime/Completion.h:
* runtime/JSModuleLoader.cpp:
(JSC::jsValueToModuleKey):
(JSC::JSModuleLoader::notifyCompleted):
(JSC::JSModuleLoader::notifyFailed):
* runtime/JSModuleLoader.h:
* runtime/ModuleLoaderPrototype.cpp:
(JSC::moduleLoaderPrototypeNotifyCompleted):
(JSC::moduleLoaderPrototypeNotifyFailed):
* runtime/ScriptFetcher.h:
(JSC::ScriptFetcher::notifyLoadCompleted):
(JSC::ScriptFetcher::notifyLoadFailed):

Source/WebCore:

No behavior change.

* bindings/js/JSMainThreadExecState.h:
(WebCore::JSMainThreadExecState::loadModule):
* bindings/js/ScriptController.cpp:
(WebCore::ScriptController::loadModuleScriptInWorld):
(WebCore::jsValueToModuleKey): Deleted.
(WebCore::ScriptController::setupModuleScriptHandlers): Deleted.
* bindings/js/ScriptController.h:
* dom/LoadableModuleScript.cpp:
(WebCore::LoadableModuleScript::notifyLoadFailed):
* dom/LoadableModuleScript.h:

LayoutTests:

* http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt:
* http/tests/security/module-no-mime-type-expected.txt:
* js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223744 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt
LayoutTests/http/tests/security/module-no-mime-type-expected.txt
LayoutTests/js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/ModuleLoaderPrototype.js
Source/JavaScriptCore/runtime/Completion.cpp
Source/JavaScriptCore/runtime/Completion.h
Source/JavaScriptCore/runtime/JSModuleLoader.cpp
Source/JavaScriptCore/runtime/JSModuleLoader.h
Source/JavaScriptCore/runtime/ModuleLoaderPrototype.cpp
Source/JavaScriptCore/runtime/ScriptFetcher.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSMainThreadExecState.h
Source/WebCore/bindings/js/ScriptController.cpp
Source/WebCore/bindings/js/ScriptController.h
Source/WebCore/dom/LoadableModuleScript.cpp
Source/WebCore/dom/LoadableModuleScript.h

index 8a4410f..ff736d9 100644 (file)
@@ -1,3 +1,14 @@
+2017-10-20  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC] ScriptFetcher should be notified directly from module pipeline
+        https://bugs.webkit.org/show_bug.cgi?id=178340
+
+        Reviewed by Sam Weinig.
+
+        * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt:
+        * http/tests/security/module-no-mime-type-expected.txt:
+        * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt:
+
 2017-10-19  Youenn Fablet  <youenn@apple.com>
 
         Add preliminary support for ServiceWorker Handle Fetch
index b45a5b2..10f0396 100644 (file)
@@ -1,3 +1,3 @@
 CONSOLE MESSAGE: Origin http://127.0.0.1:8000 is not allowed by Access-Control-Allow-Origin.
-CONSOLE MESSAGE: line 1: TypeError: Cross-origin script load denied by Cross-Origin Resource Sharing policy.
+CONSOLE MESSAGE: line 11: TypeError: Cross-origin script load denied by Cross-Origin Resource Sharing policy.
 This tests whether a deferred script load caused by a redirect is properly allowed by a nonce.
index 6ab7e3a..eceb97e 100644 (file)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 1: TypeError: 'application/octet-stream' is not a valid JavaScript MIME type.
+CONSOLE MESSAGE: line 11: TypeError: 'application/octet-stream' is not a valid JavaScript MIME type.
 Test module rejects scripts with no mime type.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
index a5df702..628df36 100644 (file)
@@ -1,3 +1,4 @@
+CONSOLE MESSAGE: line 19: Error: module is executed.
 Test window.onerror will be fired when the inlined module throws an error.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
index f16550b..478652d 100644 (file)
@@ -1,3 +1,40 @@
+2017-10-20  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC] ScriptFetcher should be notified directly from module pipeline
+        https://bugs.webkit.org/show_bug.cgi?id=178340
+
+        Reviewed by Sam Weinig.
+
+        Previously, we use JSStdFunction to let WebCore inform the module pipeline results.
+        We setup JSStdFunction to the resulted promise of the module pipeline. It is super
+        ad-hoc since JSStdFunction's lambda need extra-careful to make it non-cyclic-referenced.
+        JSStdFunction's lambda can capture variables, but they are not able to be marked by GC.
+
+        But now, we have ScriptFetcher. It is introduced after we implemented the module pipeline
+        notification mechanism by using JSStdFunction. But it is appropriate one to receive notification
+        from the module pipeline by observer style.
+
+        This patch removes the above ad-hoc JSStdFunction use. And now ScriptFetcher receives
+        completion/failure notifications from the module pipeline.
+
+        * builtins/ModuleLoaderPrototype.js:
+        (loadModule):
+        (loadAndEvaluateModule):
+        * runtime/Completion.cpp:
+        (JSC::loadModule):
+        * runtime/Completion.h:
+        * runtime/JSModuleLoader.cpp:
+        (JSC::jsValueToModuleKey):
+        (JSC::JSModuleLoader::notifyCompleted):
+        (JSC::JSModuleLoader::notifyFailed):
+        * runtime/JSModuleLoader.h:
+        * runtime/ModuleLoaderPrototype.cpp:
+        (JSC::moduleLoaderPrototypeNotifyCompleted):
+        (JSC::moduleLoaderPrototypeNotifyFailed):
+        * runtime/ScriptFetcher.h:
+        (JSC::ScriptFetcher::notifyLoadCompleted):
+        (JSC::ScriptFetcher::notifyLoadFailed):
+
 2017-10-19  JF Bastien  <jfbastien@apple.com>
 
         WebAssembly: no VM / JS version of everything but Instance
index e6ac55b..83d70b8 100644 (file)
@@ -320,9 +320,15 @@ function loadModule(moduleName, parameters, fetcher)
     // For example, take the "jquery" and return the URL for the resource.
     return this.resolve(moduleName, @undefined, fetcher).then((key) => {
         return this.requestSatisfy(this.ensureRegistered(key), parameters, fetcher);
-    }).then((entry) => {
-        return entry.key;
-    });
+    }).then(
+        (entry) => {
+            this.notifyCompleted(fetcher, entry.key);
+            return entry;
+        },
+        (error) => {
+            this.notifyFailed(fetcher, error);
+            throw error;
+        });
 }
 
 function linkAndEvaluateModule(key, fetcher)
@@ -341,8 +347,8 @@ function loadAndEvaluateModule(moduleName, parameters, fetcher)
 {
     "use strict";
 
-    return this.loadModule(moduleName, parameters, fetcher).then((key) => {
-        return this.linkAndEvaluateModule(key, fetcher);
+    return this.loadModule(moduleName, parameters, fetcher).then((entry) => {
+        return this.linkAndEvaluateModule(entry.key, fetcher);
     });
 }
 
index 05fa318..8afe870 100644 (file)
@@ -183,17 +183,17 @@ JSInternalPromise* loadAndEvaluateModule(ExecState* exec, const SourceCode& sour
     return globalObject->moduleLoader()->loadAndEvaluateModule(exec, key, jsUndefined(), scriptFetcher);
 }
 
-JSInternalPromise* loadModule(ExecState* exec, const String& moduleName, JSValue parameters, JSValue scriptFetcher)
+void loadModule(ExecState* exec, const String& moduleName, JSValue parameters, JSValue scriptFetcher)
 {
     VM& vm = exec->vm();
     JSLockHolder lock(vm);
     RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
     RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
 
-    return exec->vmEntryGlobalObject()->moduleLoader()->loadModule(exec, identifierToJSValue(vm, Identifier::fromString(exec, moduleName)), parameters, scriptFetcher);
+    exec->vmEntryGlobalObject()->moduleLoader()->loadModule(exec, identifierToJSValue(vm, Identifier::fromString(exec, moduleName)), parameters, scriptFetcher);
 }
 
-JSInternalPromise* loadModule(ExecState* exec, const SourceCode& source, JSValue scriptFetcher)
+void loadModule(ExecState* exec, const SourceCode& source, JSValue scriptFetcher)
 {
     VM& vm = exec->vm();
     JSLockHolder lock(vm);
@@ -208,9 +208,9 @@ JSInternalPromise* loadModule(ExecState* exec, const SourceCode& source, JSValue
     // Insert the given source code to the ModuleLoader registry as the fetched registry entry.
     // FIXME: Introduce JSSourceCode object to wrap around this source.
     globalObject->moduleLoader()->provideFetch(exec, key, source);
-    RETURN_IF_EXCEPTION(scope, rejectPromise(exec, globalObject));
+    RETURN_IF_EXCEPTION(scope, void());
 
-    return globalObject->moduleLoader()->loadModule(exec, key, jsUndefined(), scriptFetcher);
+    globalObject->moduleLoader()->loadModule(exec, key, jsUndefined(), scriptFetcher);
 }
 
 JSValue linkAndEvaluateModule(ExecState* exec, const Identifier& moduleKey, JSValue scriptFetcher)
index de448a4..8e953ef 100644 (file)
@@ -61,8 +61,8 @@ JS_EXPORT_PRIVATE JSInternalPromise* loadAndEvaluateModule(ExecState*, const Str
 JS_EXPORT_PRIVATE JSInternalPromise* loadAndEvaluateModule(ExecState*, const SourceCode&, JSValue scriptFetcher);
 
 // Fetch the module source, and instantiate the module record.
-JS_EXPORT_PRIVATE JSInternalPromise* loadModule(ExecState*, const String& moduleName, JSValue parameters, JSValue scriptFetcher);
-JS_EXPORT_PRIVATE JSInternalPromise* loadModule(ExecState*, const SourceCode&, JSValue scriptFetcher);
+JS_EXPORT_PRIVATE void loadModule(ExecState*, const String& moduleName, JSValue parameters, JSValue scriptFetcher);
+JS_EXPORT_PRIVATE void loadModule(ExecState*, const SourceCode&, JSValue scriptFetcher);
 
 // Link and evaluate the already linked module. This function is called in a sync manner.
 JS_EXPORT_PRIVATE JSValue linkAndEvaluateModule(ExecState*, const Identifier& moduleKey, JSValue scriptFetcher);
index 984162a..fa59a91 100644 (file)
@@ -39,6 +39,7 @@
 #include "JSMap.h"
 #include "JSModuleEnvironment.h"
 #include "JSModuleRecord.h"
+#include "JSScriptFetcher.h"
 #include "JSSourceCode.h"
 #include "ModuleAnalyzer.h"
 #include "ModuleLoaderPrototype.h"
@@ -291,4 +292,38 @@ JSModuleNamespaceObject* JSModuleLoader::getModuleNamespaceObject(ExecState* exe
     return moduleRecord->getModuleNamespace(exec);
 }
 
+static Identifier jsValueToModuleKey(ExecState* exec, JSValue value)
+{
+    if (value.isSymbol())
+        return Identifier::fromUid(jsCast<Symbol*>(value)->privateName());
+    ASSERT(value.isString());
+    return asString(value)->toIdentifier(exec);
+}
+
+JSValue JSModuleLoader::notifyCompleted(ExecState* exec, JSValue scriptFetcher, JSValue key)
+{
+    auto* fetcherWrapper = jsDynamicCast<JSScriptFetcher*>(exec->vm(), scriptFetcher);
+    if (!fetcherWrapper)
+        return jsUndefined();
+    auto* fetcher = fetcherWrapper->fetcher();
+    if (!fetcher)
+        return jsUndefined();
+
+    Identifier moduleKey = jsValueToModuleKey(exec, key);
+    fetcher->notifyLoadCompleted(*moduleKey.impl());
+    return jsUndefined();
+}
+
+JSValue JSModuleLoader::notifyFailed(ExecState* exec, JSValue scriptFetcher, JSValue errorValue)
+{
+    auto* fetcherWrapper = jsDynamicCast<JSScriptFetcher*>(exec->vm(), scriptFetcher);
+    if (!fetcherWrapper)
+        return jsUndefined();
+    auto* fetcher = fetcherWrapper->fetcher();
+    if (!fetcher)
+        return jsUndefined();
+    fetcher->notifyLoadFailed(exec, errorValue);
+    return jsUndefined();
+}
+
 } // namespace JSC
index 5404199..2ec9d47 100644 (file)
@@ -68,6 +68,8 @@ public:
     JSInternalPromise* loadModule(ExecState*, JSValue moduleName, JSValue parameters, JSValue scriptFetcher);
     JSValue linkAndEvaluateModule(ExecState*, JSValue moduleKey, JSValue scriptFetcher);
     JSInternalPromise* requestImportModule(ExecState*, const Identifier&, JSValue parameters, JSValue scriptFetcher);
+    JSValue notifyCompleted(ExecState*, JSValue scriptFetcher, JSValue key);
+    JSValue notifyFailed(ExecState*, JSValue scriptFetcher, JSValue error);
 
     // Platform dependent hooked APIs.
     JSInternalPromise* importModule(ExecState*, JSString* moduleName, JSValue parameters, const SourceOrigin& referrer);
index 3d4f44a..b3f00c5 100644 (file)
@@ -56,6 +56,8 @@ static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeResolve(ExecState*);
 static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeResolveSync(ExecState*);
 static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeFetch(ExecState*);
 static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeGetModuleNamespaceObject(ExecState*);
+static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeNotifyCompleted(ExecState*);
+static EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeNotifyFailed(ExecState*);
 
 }
 
@@ -90,6 +92,8 @@ const ClassInfo ModuleLoaderPrototype::s_info = { "ModuleLoader", &Base::s_info,
     resolve                        moduleLoaderPrototypeResolve                        DontEnum|Function 2
     resolveSync                    moduleLoaderPrototypeResolveSync                    DontEnum|Function 2
     fetch                          moduleLoaderPrototypeFetch                          DontEnum|Function 3
+    notifyCompleted                moduleLoaderPrototypeNotifyCompleted                DontEnum|Function 2
+    notifyFailed                   moduleLoaderPrototypeNotifyFailed                   DontEnum|Function 2
 @end
 */
 
@@ -170,6 +174,24 @@ EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeModuleDeclarationInstantiation
     return JSValue::encode(jsUndefined());
 }
 
+EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeNotifyCompleted(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, exec->thisValue());
+    if (!loader)
+        return JSValue::encode(jsUndefined());
+    return JSValue::encode(loader->notifyCompleted(exec, exec->argument(0), exec->argument(1)));
+}
+
+EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeNotifyFailed(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, exec->thisValue());
+    if (!loader)
+        return JSValue::encode(jsUndefined());
+    return JSValue::encode(loader->notifyFailed(exec, exec->argument(0), exec->argument(1)));
+}
+
 // ------------------------------ Hook Functions ---------------------------
 
 EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeResolve(ExecState* exec)
index bd0ae29..7a69622 100644 (file)
 
 #pragma once
 
+#include "JSCJSValue.h"
 #include <wtf/RefCounted.h>
 
 namespace JSC {
 
+class ExecState;
+
 class ScriptFetcher : public RefCounted<ScriptFetcher> {
 public:
     virtual ~ScriptFetcher() { }
+
+    virtual void notifyLoadCompleted(UniquedStringImpl&) { }
+    virtual void notifyLoadFailed(ExecState*, JSValue) { }
 };
 
 } // namespace JSC
index 6a1c9b1..90d87af 100644 (file)
@@ -1,3 +1,23 @@
+2017-10-20  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC] ScriptFetcher should be notified directly from module pipeline
+        https://bugs.webkit.org/show_bug.cgi?id=178340
+
+        Reviewed by Sam Weinig.
+
+        No behavior change.
+
+        * bindings/js/JSMainThreadExecState.h:
+        (WebCore::JSMainThreadExecState::loadModule):
+        * bindings/js/ScriptController.cpp:
+        (WebCore::ScriptController::loadModuleScriptInWorld):
+        (WebCore::jsValueToModuleKey): Deleted.
+        (WebCore::ScriptController::setupModuleScriptHandlers): Deleted.
+        * bindings/js/ScriptController.h:
+        * dom/LoadableModuleScript.cpp:
+        (WebCore::LoadableModuleScript::notifyLoadFailed):
+        * dom/LoadableModuleScript.h:
+
 2017-10-19  Ms2ger  <Ms2ger@igalia.com>
 
         Remove proprietary constants from WebGL2RenderingContext.
index a4461a1..c09ea15 100644 (file)
@@ -90,16 +90,16 @@ public:
         task.run(exec);
     }
 
-    static JSC::JSInternalPromise& loadModule(JSC::ExecState& state, const String& moduleName, JSC::JSValue parameters, JSC::JSValue scriptFetcher)
+    static void loadModule(JSC::ExecState& state, const String& moduleName, JSC::JSValue parameters, JSC::JSValue scriptFetcher)
     {
         JSMainThreadExecState currentState(&state);
-        return *JSC::loadModule(&state, moduleName, parameters, scriptFetcher);
+        JSC::loadModule(&state, moduleName, parameters, scriptFetcher);
     }
 
-    static JSC::JSInternalPromise& loadModule(JSC::ExecState& state, const JSC::SourceCode& sourceCode, JSC::JSValue scriptFetcher)
+    static void loadModule(JSC::ExecState& state, const JSC::SourceCode& sourceCode, JSC::JSValue scriptFetcher)
     {
         JSMainThreadExecState currentState(&state);
-        return *JSC::loadModule(&state, sourceCode, scriptFetcher);
+        JSC::loadModule(&state, sourceCode, scriptFetcher);
     }
 
     static JSC::JSValue linkAndEvaluateModule(JSC::ExecState& state, const JSC::Identifier& moduleKey, JSC::JSValue scriptFetcher, NakedPtr<JSC::Exception>& returnedException)
index ed2c903..f708298 100644 (file)
@@ -40,7 +40,6 @@
 #include "JSMainThreadExecState.h"
 #include "LoadableModuleScript.h"
 #include "MainFrame.h"
-#include "ModuleFetchFailureKind.h"
 #include "ModuleFetchParameters.h"
 #include "NP_jsobject.h"
 #include "Page.h"
@@ -62,7 +61,6 @@
 #include <runtime/JSInternalPromise.h>
 #include <runtime/JSLock.h>
 #include <runtime/JSModuleRecord.h>
-#include <runtime/JSNativeStdFunction.h>
 #include <runtime/JSScriptFetchParameters.h>
 #include <runtime/JSScriptFetcher.h>
 #include <wtf/MemoryPressureHandler.h>
@@ -199,8 +197,7 @@ void ScriptController::loadModuleScriptInWorld(LoadableModuleScript& moduleScrip
     auto& proxy = *windowProxy(world);
     auto& state = *proxy.window()->globalExec();
 
-    auto& promise = JSMainThreadExecState::loadModule(state, moduleName, JSC::JSScriptFetchParameters::create(state.vm(), WTFMove(topLevelFetchParameters)), JSC::JSScriptFetcher::create(state.vm(), { &moduleScript }));
-    setupModuleScriptHandlers(moduleScript, promise, world);
+    JSMainThreadExecState::loadModule(state, moduleName, JSC::JSScriptFetchParameters::create(state.vm(), WTFMove(topLevelFetchParameters)), JSC::JSScriptFetcher::create(state.vm(), { &moduleScript }));
 }
 
 void ScriptController::loadModuleScript(LoadableModuleScript& moduleScript, const String& moduleName, Ref<ModuleFetchParameters>&& topLevelFetchParameters)
@@ -215,8 +212,7 @@ void ScriptController::loadModuleScriptInWorld(LoadableModuleScript& moduleScrip
     auto& proxy = *windowProxy(world);
     auto& state = *proxy.window()->globalExec();
 
-    auto& promise = JSMainThreadExecState::loadModule(state, sourceCode.jsSourceCode(), JSC::JSScriptFetcher::create(state.vm(), { &moduleScript }));
-    setupModuleScriptHandlers(moduleScript, promise, world);
+    JSMainThreadExecState::loadModule(state, sourceCode.jsSourceCode(), JSC::JSScriptFetcher::create(state.vm(), { &moduleScript }));
 }
 
 void ScriptController::loadModuleScript(LoadableModuleScript& moduleScript, const ScriptSourceCode& sourceCode)
@@ -364,68 +360,6 @@ JSDOMWindowProxy* ScriptController::initScript(DOMWrapperWorld& world)
     return &windowProxy;
 }
 
-static Identifier jsValueToModuleKey(ExecState* exec, JSValue value)
-{
-    if (value.isSymbol())
-        return Identifier::fromUid(jsCast<Symbol*>(value)->privateName());
-    ASSERT(value.isString());
-    return asString(value)->toIdentifier(exec);
-}
-
-void ScriptController::setupModuleScriptHandlers(LoadableModuleScript& moduleScriptRef, JSInternalPromise& promise, DOMWrapperWorld& world)
-{
-    auto& proxy = *windowProxy(world);
-    auto& state = *proxy.window()->globalExec();
-
-    // It is not guaranteed that either fulfillHandler or rejectHandler is eventually called.
-    // For example, if the page load is canceled, the DeferredPromise used in the module loader pipeline will stop executing JS code.
-    // Thus the promise returned from this function could remain unresolved.
-
-    RefPtr<LoadableModuleScript> moduleScript(&moduleScriptRef);
-
-    auto& fulfillHandler = *JSNativeStdFunction::create(state.vm(), proxy.window(), 1, String(), [moduleScript](ExecState* exec) {
-        Identifier moduleKey = jsValueToModuleKey(exec, exec->argument(0));
-        moduleScript->notifyLoadCompleted(*moduleKey.impl());
-        return JSValue::encode(jsUndefined());
-    });
-
-    auto& rejectHandler = *JSNativeStdFunction::create(state.vm(), proxy.window(), 1, String(), [moduleScript](ExecState* exec) {
-        VM& vm = exec->vm();
-        JSValue errorValue = exec->argument(0);
-        if (errorValue.isObject()) {
-            auto* object = JSC::asObject(errorValue);
-            if (JSValue failureKindValue = object->getDirect(vm, static_cast<JSVMClientData&>(*vm.clientData).builtinNames().failureKindPrivateName())) {
-                // This is host propagated error in the module loader pipeline.
-                switch (static_cast<ModuleFetchFailureKind>(failureKindValue.asInt32())) {
-                case ModuleFetchFailureKind::WasErrored:
-                    moduleScript->notifyLoadFailed(LoadableScript::Error {
-                        LoadableScript::ErrorType::CachedScript,
-                        std::nullopt
-                    });
-                    break;
-                case ModuleFetchFailureKind::WasCanceled:
-                    moduleScript->notifyLoadWasCanceled();
-                    break;
-                }
-                return JSValue::encode(jsUndefined());
-            }
-        }
-
-        auto scope = DECLARE_CATCH_SCOPE(vm);
-        moduleScript->notifyLoadFailed(LoadableScript::Error {
-            LoadableScript::ErrorType::CachedScript,
-            LoadableScript::ConsoleMessage {
-                MessageSource::JS,
-                MessageLevel::Error,
-                retrieveErrorMessage(*exec, vm, errorValue, scope),
-            }
-        });
-        return JSValue::encode(jsUndefined());
-    });
-
-    promise.then(&state, &fulfillHandler, &rejectHandler);
-}
-
 TextPosition ScriptController::eventHandlerPosition() const
 {
     // FIXME: If we are not currently parsing, we should use our current location
index d85f66d..6dd7c91 100644 (file)
@@ -182,7 +182,6 @@ public:
 
 private:
     WEBCORE_EXPORT JSDOMWindowProxy* initScript(DOMWrapperWorld&);
-    void setupModuleScriptHandlers(LoadableModuleScript&, JSC::JSInternalPromise&, DOMWrapperWorld&);
 
     void disconnectPlatformScriptObjects();
 
index 267ff01..e5c8cb3 100644 (file)
 
 #include "Document.h"
 #include "Frame.h"
+#include "JSDOMExceptionHandling.h"
+#include "ModuleFetchFailureKind.h"
 #include "ModuleFetchParameters.h"
 #include "ScriptController.h"
 #include "ScriptElement.h"
+#include "WebCoreJSClientData.h"
+#include <heap/StrongInlines.h>
+#include <runtime/CatchScope.h>
 
 namespace WebCore {
 
@@ -69,6 +74,39 @@ void LoadableModuleScript::notifyLoadCompleted(UniquedStringImpl& moduleKey)
     notifyClientFinished();
 }
 
+void LoadableModuleScript::notifyLoadFailed(JSC::ExecState* exec, JSC::JSValue errorValue)
+{
+    JSC::VM& vm = exec->vm();
+    if (errorValue.isObject()) {
+        auto* object = JSC::asObject(errorValue);
+        if (JSC::JSValue failureKindValue = object->getDirect(vm, static_cast<JSVMClientData&>(*vm.clientData).builtinNames().failureKindPrivateName())) {
+            // This is host propagated error in the module loader pipeline.
+            switch (static_cast<ModuleFetchFailureKind>(failureKindValue.asInt32())) {
+            case ModuleFetchFailureKind::WasErrored:
+                notifyLoadFailed(LoadableScript::Error {
+                    LoadableScript::ErrorType::CachedScript,
+                    std::nullopt
+                });
+                break;
+            case ModuleFetchFailureKind::WasCanceled:
+                notifyLoadWasCanceled();
+                break;
+            }
+            return;
+        }
+    }
+
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+    notifyLoadFailed(LoadableScript::Error {
+        LoadableScript::ErrorType::CachedScript,
+        LoadableScript::ConsoleMessage {
+            MessageSource::JS,
+            MessageLevel::Error,
+            retrieveErrorMessage(*exec, vm, errorValue, scope),
+        }
+    });
+}
+
 void LoadableModuleScript::notifyLoadFailed(LoadableScript::Error&& error)
 {
     m_error = WTFMove(error);
index ba1fe1d..e141d19 100644 (file)
@@ -53,15 +53,17 @@ public:
     void load(Document&, const URL& rootURL);
     void load(Document&, const ScriptSourceCode&);
 
-    void notifyLoadCompleted(UniquedStringImpl&);
-    void notifyLoadFailed(LoadableScript::Error&&);
-    void notifyLoadWasCanceled();
-
     UniquedStringImpl* moduleKey() const { return m_moduleKey.get(); }
 
+    void notifyLoadCompleted(UniquedStringImpl&) final;
+    void notifyLoadFailed(JSC::ExecState*, JSC::JSValue) final;
+
 private:
     LoadableModuleScript(const String& nonce, const String& integrity, const String& crossOriginMode, const String& charset, const AtomicString& initiatorName, bool isInUserAgentShadowTree);
 
+    void notifyLoadFailed(LoadableScript::Error&&);
+    void notifyLoadWasCanceled();
+
     Ref<ModuleFetchParameters> m_parameters;
     RefPtr<UniquedStringImpl> m_moduleKey;
     std::optional<LoadableScript::Error> m_error;