| Differences between
and this patch
- a/Source/WebCore/ChangeLog +34 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2021-02-08  Yusuke Suzuki  <ysuzuki@apple.com>
2
3
        JS Modules in Workers
4
        https://bugs.webkit.org/show_bug.cgi?id=164860
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * dom/LoadableModuleScript.cpp:
9
        (WebCore::LoadableModuleScript::load): Deleted.
10
        * dom/LoadableModuleScript.h:
11
        * dom/ScriptElement.cpp:
12
        (WebCore::ScriptElement::requestModuleScript):
13
        * workers/Worker.cpp:
14
        (WebCore::Worker::Worker):
15
        (WebCore::Worker::create):
16
        (WebCore::Worker::notifyFinished):
17
        * workers/Worker.h:
18
        * workers/Worker.idl:
19
        * workers/WorkerGlobalScopeProxy.h:
20
        * workers/WorkerMessagingProxy.cpp:
21
        (WebCore::WorkerMessagingProxy::startWorkerGlobalScope):
22
        * workers/WorkerMessagingProxy.h:
23
        * workers/WorkerOrWorkletScriptController.cpp:
24
        (WebCore::jsValueToModuleKey):
25
        (WebCore::WorkerOrWorkletScriptController::loadModuleSynchronously):
26
        (WebCore::WorkerOrWorkletScriptController::linkAndEvaluateModule):
27
        * workers/WorkerOrWorkletScriptController.h:
28
        * workers/WorkerThread.cpp:
29
        (WebCore::WorkerParameters::isolatedCopy const):
30
        (WebCore::WorkerThread::evaluateScriptIfNecessary):
31
        * workers/WorkerThread.h:
32
        * workers/service/context/ServiceWorkerThread.cpp:
33
        (WebCore::ServiceWorkerThread::ServiceWorkerThread):
34
1
2021-02-07  Lauro Moura  <lmoura@igalia.com>
35
2021-02-07  Lauro Moura  <lmoura@igalia.com>
2
36
3
        REGRESSION(r272379) [WPE] imported/w3c/web-platform-tests/mathml/relations/css-styling/mathvariant tests are Image Failing
37
        REGRESSION(r272379) [WPE] imported/w3c/web-platform-tests/mathml/relations/css-styling/mathvariant tests are Image Failing
- a/Source/WebCore/dom/LoadableModuleScript.cpp -12 lines
Lines 88-103 void LoadableModuleScript::execute(ScriptElement& scriptElement) a/Source/WebCore/dom/LoadableModuleScript.cpp_sec1
88
    scriptElement.executeModuleScript(*this);
88
    scriptElement.executeModuleScript(*this);
89
}
89
}
90
90
91
void LoadableModuleScript::load(Document& document, const URL& rootURL)
92
{
93
    if (auto* frame = document.frame())
94
        frame->script().loadModuleScript(*this, rootURL.string(), m_parameters.copyRef());
95
}
96
97
void LoadableModuleScript::load(Document& document, const ScriptSourceCode& sourceCode)
98
{
99
    if (auto* frame = document.frame())
100
        frame->script().loadModuleScript(*this, sourceCode);
101
}
102
103
}
91
}
- a/Source/WebCore/dom/LoadableModuleScript.h -3 / +2 lines
Lines 50-64 class LoadableModuleScript final : public LoadableScript { a/Source/WebCore/dom/LoadableModuleScript.h_sec1
50
50
51
    void setError(Error&&);
51
    void setError(Error&&);
52
52
53
    void load(Document&, const URL& rootURL);
54
    void load(Document&, const ScriptSourceCode&);
55
56
    void notifyLoadCompleted(UniquedStringImpl&);
53
    void notifyLoadCompleted(UniquedStringImpl&);
57
    void notifyLoadFailed(LoadableScript::Error&&);
54
    void notifyLoadFailed(LoadableScript::Error&&);
58
    void notifyLoadWasCanceled();
55
    void notifyLoadWasCanceled();
59
56
60
    UniquedStringImpl* moduleKey() const { return m_moduleKey.get(); }
57
    UniquedStringImpl* moduleKey() const { return m_moduleKey.get(); }
61
58
59
    ModuleFetchParameters& parameters() { return m_parameters.get(); }
60
62
private:
61
private:
63
    LoadableModuleScript(const String& nonce, const String& integrity, ReferrerPolicy, const String& crossOriginMode, const String& charset, const AtomString& initiatorName, bool isInUserAgentShadowTree);
62
    LoadableModuleScript(const String& nonce, const String& integrity, ReferrerPolicy, const String& crossOriginMode, const String& charset, const AtomString& initiatorName, bool isInUserAgentShadowTree);
64
63
- a/Source/WebCore/dom/ScriptElement.cpp -2 / +7 lines
Lines 42-47 a/Source/WebCore/dom/ScriptElement.cpp_sec1
42
#include "LoadableClassicScript.h"
42
#include "LoadableClassicScript.h"
43
#include "LoadableModuleScript.h"
43
#include "LoadableModuleScript.h"
44
#include "MIMETypeRegistry.h"
44
#include "MIMETypeRegistry.h"
45
#include "ModuleFetchParameters.h"
45
#include "PendingScript.h"
46
#include "PendingScript.h"
46
#include "RuntimeApplicationChecks.h"
47
#include "RuntimeApplicationChecks.h"
47
#include "SVGScriptElement.h"
48
#include "SVGScriptElement.h"
Lines 351-358 bool ScriptElement::requestModuleScript(const TextPosition& scriptStartPosition) a/Source/WebCore/dom/ScriptElement.cpp_sec2
351
            scriptCharset(),
352
            scriptCharset(),
352
            m_element.localName(),
353
            m_element.localName(),
353
            m_element.isInUserAgentShadowTree());
354
            m_element.isInUserAgentShadowTree());
354
        script->load(m_element.document(), moduleScriptRootURL);
355
        m_loadableScript = WTFMove(script);
355
        m_loadableScript = WTFMove(script);
356
        if (auto* frame = m_element.document().frame()) {
357
            auto& script = downcast<LoadableModuleScript>(*m_loadableScript.get());
358
            frame->script().loadModuleScript(script, moduleScriptRootURL.string(), makeRef(script.parameters()));
359
        }
356
        return true;
360
        return true;
357
    }
361
    }
358
362
Lines 367-374 bool ScriptElement::requestModuleScript(const TextPosition& scriptStartPosition) a/Source/WebCore/dom/ScriptElement.cpp_sec3
367
    if (!contentSecurityPolicy.allowInlineScript(m_element.document().url().string(), m_startLineNumber, sourceCode.source().toStringWithoutCopying(), hasKnownNonce))
371
    if (!contentSecurityPolicy.allowInlineScript(m_element.document().url().string(), m_startLineNumber, sourceCode.source().toStringWithoutCopying(), hasKnownNonce))
368
        return false;
372
        return false;
369
373
370
    script->load(m_element.document(), sourceCode);
371
    m_loadableScript = WTFMove(script);
374
    m_loadableScript = WTFMove(script);
375
    if (auto* frame = m_element.document().frame())
376
        frame->script().loadModuleScript(downcast<LoadableModuleScript>(*m_loadableScript.get()), sourceCode);
372
    return true;
377
    return true;
373
}
378
}
374
379
- a/Source/WebCore/workers/Worker.cpp -2 / +7 lines
Lines 70-75 inline Worker::Worker(ScriptExecutionContext& context, JSC::RuntimeFlags runtime a/Source/WebCore/workers/Worker.cpp_sec1
70
    , m_identifier("worker:" + Inspector::IdentifiersFactory::createIdentifier())
70
    , m_identifier("worker:" + Inspector::IdentifiersFactory::createIdentifier())
71
    , m_contextProxy(WorkerGlobalScopeProxy::create(*this))
71
    , m_contextProxy(WorkerGlobalScopeProxy::create(*this))
72
    , m_runtimeFlags(runtimeFlags)
72
    , m_runtimeFlags(runtimeFlags)
73
    , m_type(options.type)
74
    , m_credentials(options.credentials)
73
{
75
{
74
    static bool addedListener;
76
    static bool addedListener;
75
    if (!addedListener) {
77
    if (!addedListener) {
Lines 113-122 ExceptionOr<Ref<Worker>> Worker::create(ScriptExecutionContext& context, JSC::Ru a/Source/WebCore/workers/Worker.cpp_sec2
113
115
114
    FetchOptions fetchOptions;
116
    FetchOptions fetchOptions;
115
    fetchOptions.mode = FetchOptions::Mode::SameOrigin;
117
    fetchOptions.mode = FetchOptions::Mode::SameOrigin;
118
    if (worker->m_type == WorkerType::Module)
119
        fetchOptions.credentials = worker->m_credentials;
116
    fetchOptions.cache = FetchOptions::Cache::Default;
120
    fetchOptions.cache = FetchOptions::Cache::Default;
117
    fetchOptions.redirect = FetchOptions::Redirect::Follow;
121
    fetchOptions.redirect = FetchOptions::Redirect::Follow;
118
    fetchOptions.destination = FetchOptions::Destination::Worker;
122
    fetchOptions.destination = FetchOptions::Destination::Worker;
119
    worker->m_scriptLoader->loadAsynchronously(context, WTFMove(request), WTFMove(fetchOptions), contentSecurityPolicyEnforcement, ServiceWorkersMode::All, worker);
123
    worker->m_scriptLoader->loadAsynchronously(context, WTFMove(request), WTFMove(fetchOptions), contentSecurityPolicyEnforcement, ServiceWorkersMode::All, worker.get());
124
120
    return worker;
125
    return worker;
121
}
126
}
122
127
Lines 215-221 void Worker::notifyFinished() a/Source/WebCore/workers/Worker.cpp_sec3
215
    ReferrerPolicy referrerPolicy = ReferrerPolicy::EmptyString;
220
    ReferrerPolicy referrerPolicy = ReferrerPolicy::EmptyString;
216
    if (auto policy = parseReferrerPolicy(m_scriptLoader->referrerPolicy(), ReferrerPolicySource::HTTPHeader))
221
    if (auto policy = parseReferrerPolicy(m_scriptLoader->referrerPolicy(), ReferrerPolicySource::HTTPHeader))
217
        referrerPolicy = *policy;
222
        referrerPolicy = *policy;
218
    m_contextProxy.startWorkerGlobalScope(m_scriptLoader->url(), m_name, context->userAgent(m_scriptLoader->url()), isOnline, m_scriptLoader->script(), contentSecurityPolicyResponseHeaders, m_shouldBypassMainWorldContentSecurityPolicy, m_workerCreationTime, referrerPolicy, m_runtimeFlags);
223
    m_contextProxy.startWorkerGlobalScope(m_scriptLoader->url(), m_name, context->userAgent(m_scriptLoader->url()), isOnline, m_scriptLoader->script(), contentSecurityPolicyResponseHeaders, m_shouldBypassMainWorldContentSecurityPolicy, m_workerCreationTime, referrerPolicy, m_type, m_credentials, m_runtimeFlags);
219
    InspectorInstrumentation::scriptImported(*context, m_scriptLoader->identifier(), m_scriptLoader->script());
224
    InspectorInstrumentation::scriptImported(*context, m_scriptLoader->identifier(), m_scriptLoader->script());
220
}
225
}
221
226
- a/Source/WebCore/workers/Worker.h +8 lines
Lines 29-37 a/Source/WebCore/workers/Worker.h_sec1
29
#include "ActiveDOMObject.h"
29
#include "ActiveDOMObject.h"
30
#include "ContentSecurityPolicyResponseHeaders.h"
30
#include "ContentSecurityPolicyResponseHeaders.h"
31
#include "EventTarget.h"
31
#include "EventTarget.h"
32
#include "FetchRequestCredentials.h"
32
#include "MessagePort.h"
33
#include "MessagePort.h"
33
#include "PostMessageOptions.h"
34
#include "PostMessageOptions.h"
34
#include "WorkerScriptLoaderClient.h"
35
#include "WorkerScriptLoaderClient.h"
36
#include "WorkerType.h"
35
#include <JavaScriptCore/RuntimeFlags.h>
37
#include <JavaScriptCore/RuntimeFlags.h>
36
#include <wtf/MonotonicTime.h>
38
#include <wtf/MonotonicTime.h>
37
#include <wtf/Optional.h>
39
#include <wtf/Optional.h>
Lines 55-60 class Worker final : public AbstractWorker, public ActiveDOMObject, private Work a/Source/WebCore/workers/Worker.h_sec2
55
    WTF_MAKE_ISO_ALLOCATED(Worker);
57
    WTF_MAKE_ISO_ALLOCATED(Worker);
56
public:
58
public:
57
    struct Options {
59
    struct Options {
60
        WorkerType type;
61
        FetchRequestCredentials credentials;
58
        String name;
62
        String name;
59
    };
63
    };
60
    static ExceptionOr<Ref<Worker>> create(ScriptExecutionContext&, JSC::RuntimeFlags, const String& url, const Options&);
64
    static ExceptionOr<Ref<Worker>> create(ScriptExecutionContext&, JSC::RuntimeFlags, const String& url, const Options&);
Lines 79-84 class Worker final : public AbstractWorker, public ActiveDOMObject, private Work a/Source/WebCore/workers/Worker.h_sec3
79
    void postTaskToWorkerGlobalScope(Function<void(ScriptExecutionContext&)>&&);
83
    void postTaskToWorkerGlobalScope(Function<void(ScriptExecutionContext&)>&&);
80
#endif
84
#endif
81
85
86
    WorkerType type() const { return m_type; }
87
82
private:
88
private:
83
    explicit Worker(ScriptExecutionContext&, JSC::RuntimeFlags, const Options&);
89
    explicit Worker(ScriptExecutionContext&, JSC::RuntimeFlags, const Options&);
84
90
Lines 112-117 class Worker final : public AbstractWorker, public ActiveDOMObject, private Work a/Source/WebCore/workers/Worker.h_sec4
112
#if ENABLE(WEB_RTC)
118
#if ENABLE(WEB_RTC)
113
    HashSet<String> m_transformers;
119
    HashSet<String> m_transformers;
114
#endif
120
#endif
121
    WorkerType m_type { WorkerType::Classic };
122
    FetchRequestCredentials m_credentials { FetchRequestCredentials::SameOrigin };
115
};
123
};
116
124
117
} // namespace WebCore
125
} // namespace WebCore
- a/Source/WebCore/workers/Worker.idl +2 lines
Lines 38-43 a/Source/WebCore/workers/Worker.idl_sec1
38
};
38
};
39
39
40
dictionary WorkerOptions {
40
dictionary WorkerOptions {
41
    WorkerType type = "classic";
42
    FetchRequestCredentials credentials = "same-origin"; // credentials is only used if type is "module"
41
    DOMString name = "";
43
    DOMString name = "";
42
};
44
};
43
45
- a/Source/WebCore/workers/WorkerGlobalScopeProxy.h -1 / +1 lines
Lines 48-54 class WorkerGlobalScopeProxy { a/Source/WebCore/workers/WorkerGlobalScopeProxy.h_sec1
48
public:
48
public:
49
    static WorkerGlobalScopeProxy& create(Worker&);
49
    static WorkerGlobalScopeProxy& create(Worker&);
50
50
51
    virtual void startWorkerGlobalScope(const URL& scriptURL, const String& name, const String& userAgent, bool isOnline, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, MonotonicTime timeOrigin, ReferrerPolicy, JSC::RuntimeFlags) = 0;
51
    virtual void startWorkerGlobalScope(const URL& scriptURL, const String& name, const String& userAgent, bool isOnline, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, MonotonicTime timeOrigin, ReferrerPolicy, WorkerType workerType, FetchRequestCredentials credentials, JSC::RuntimeFlags) = 0;
52
    virtual void terminateWorkerGlobalScope() = 0;
52
    virtual void terminateWorkerGlobalScope() = 0;
53
    virtual void postMessageToWorkerGlobalScope(MessageWithMessagePorts&&) = 0;
53
    virtual void postMessageToWorkerGlobalScope(MessageWithMessagePorts&&) = 0;
54
    virtual void postTaskToWorkerGlobalScope(Function<void(ScriptExecutionContext&)>&&) = 0;
54
    virtual void postTaskToWorkerGlobalScope(Function<void(ScriptExecutionContext&)>&&) = 0;
- a/Source/WebCore/workers/WorkerMessagingProxy.cpp -2 / +2 lines
Lines 73-79 WorkerMessagingProxy::~WorkerMessagingProxy() a/Source/WebCore/workers/WorkerMessagingProxy.cpp_sec1
73
        || (is<WorkerGlobalScope>(*m_scriptExecutionContext) && downcast<WorkerGlobalScope>(*m_scriptExecutionContext).thread().thread() == &Thread::current()));
73
        || (is<WorkerGlobalScope>(*m_scriptExecutionContext) && downcast<WorkerGlobalScope>(*m_scriptExecutionContext).thread().thread() == &Thread::current()));
74
}
74
}
75
75
76
void WorkerMessagingProxy::startWorkerGlobalScope(const URL& scriptURL, const String& name, const String& userAgent, bool isOnline, const String& sourceCode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, MonotonicTime timeOrigin, ReferrerPolicy referrerPolicy, JSC::RuntimeFlags runtimeFlags)
76
void WorkerMessagingProxy::startWorkerGlobalScope(const URL& scriptURL, const String& name, const String& userAgent, bool isOnline, const String& sourceCode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, MonotonicTime timeOrigin, ReferrerPolicy referrerPolicy, WorkerType workerType, FetchRequestCredentials credentials, JSC::RuntimeFlags runtimeFlags)
77
{
77
{
78
    // FIXME: This need to be revisited when we support nested worker one day
78
    // FIXME: This need to be revisited when we support nested worker one day
79
    ASSERT(m_scriptExecutionContext);
79
    ASSERT(m_scriptExecutionContext);
Lines 89-95 void WorkerMessagingProxy::startWorkerGlobalScope(const URL& scriptURL, const St a/Source/WebCore/workers/WorkerMessagingProxy.cpp_sec2
89
89
90
    SocketProvider* socketProvider = document.socketProvider();
90
    SocketProvider* socketProvider = document.socketProvider();
91
91
92
    WorkerParameters params = { scriptURL, name, identifier, userAgent, isOnline, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, timeOrigin, referrerPolicy, document.settingsValues() };
92
    WorkerParameters params = { scriptURL, name, identifier, userAgent, isOnline, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, timeOrigin, referrerPolicy, workerType, credentials, document.settingsValues() };
93
    auto thread = DedicatedWorkerThread::create(params, sourceCode, *this, *this, *this, startMode, document.topOrigin(), proxy, socketProvider, runtimeFlags);
93
    auto thread = DedicatedWorkerThread::create(params, sourceCode, *this, *this, *this, startMode, document.topOrigin(), proxy, socketProvider, runtimeFlags);
94
94
95
    workerThreadCreated(thread.get());
95
    workerThreadCreated(thread.get());
- a/Source/WebCore/workers/WorkerMessagingProxy.h -1 / +1 lines
Lines 50-56 class WorkerMessagingProxy final : public ThreadSafeRefCounted<WorkerMessagingPr a/Source/WebCore/workers/WorkerMessagingProxy.h_sec1
50
private:
50
private:
51
    // Implementations of WorkerGlobalScopeProxy.
51
    // Implementations of WorkerGlobalScopeProxy.
52
    // (Only use these functions in the worker object thread.)
52
    // (Only use these functions in the worker object thread.)
53
    void startWorkerGlobalScope(const URL& scriptURL, const String& name, const String& userAgent, bool isOnline, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, MonotonicTime timeOrigin, ReferrerPolicy, JSC::RuntimeFlags) final;
53
    void startWorkerGlobalScope(const URL& scriptURL, const String& name, const String& userAgent, bool isOnline, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, MonotonicTime timeOrigin, ReferrerPolicy, WorkerType workerType, FetchRequestCredentials credentials, JSC::RuntimeFlags) final;
54
    void terminateWorkerGlobalScope() final;
54
    void terminateWorkerGlobalScope() final;
55
    void postMessageToWorkerGlobalScope(MessageWithMessagePorts&&) final;
55
    void postMessageToWorkerGlobalScope(MessageWithMessagePorts&&) final;
56
    void postTaskToWorkerGlobalScope(Function<void(ScriptExecutionContext&)>&&) final;
56
    void postTaskToWorkerGlobalScope(Function<void(ScriptExecutionContext&)>&&) final;
- a/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp -1 / +125 lines
Lines 35-40 a/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp_sec1
35
#include "JSExecState.h"
35
#include "JSExecState.h"
36
#include "JSPaintWorkletGlobalScope.h"
36
#include "JSPaintWorkletGlobalScope.h"
37
#include "JSServiceWorkerGlobalScope.h"
37
#include "JSServiceWorkerGlobalScope.h"
38
#include "LoadableModuleScript.h"
39
#include "ModuleFetchFailureKind.h"
40
#include "ModuleFetchParameters.h"
38
#include "ScriptSourceCode.h"
41
#include "ScriptSourceCode.h"
39
#include "WebCoreJSClientData.h"
42
#include "WebCoreJSClientData.h"
40
#include "WorkerConsoleClient.h"
43
#include "WorkerConsoleClient.h"
Lines 43-49 a/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp_sec2
43
#include <JavaScriptCore/Exception.h>
46
#include <JavaScriptCore/Exception.h>
44
#include <JavaScriptCore/ExceptionHelpers.h>
47
#include <JavaScriptCore/ExceptionHelpers.h>
45
#include <JavaScriptCore/GCActivityCallback.h>
48
#include <JavaScriptCore/GCActivityCallback.h>
49
#include <JavaScriptCore/JSInternalPromise.h>
46
#include <JavaScriptCore/JSLock.h>
50
#include <JavaScriptCore/JSLock.h>
51
#include <JavaScriptCore/JSNativeStdFunction.h>
52
#include <JavaScriptCore/JSScriptFetchParameters.h>
53
#include <JavaScriptCore/JSScriptFetcher.h>
47
#include <JavaScriptCore/StrongInlines.h>
54
#include <JavaScriptCore/StrongInlines.h>
48
55
49
namespace WebCore {
56
namespace WebCore {
Lines 228-234 void WorkerOrWorkletScriptController::evaluate(const ScriptSourceCode& sourceCod a/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp_sec3
228
    }
235
    }
229
}
236
}
230
237
231
template<typename JSGlobalScopePrototype, typename JSGlobalScope, typename GlobalScope>
238
static Identifier jsValueToModuleKey(JSGlobalObject* lexicalGlobalObject, JSValue value)
239
{
240
    if (value.isSymbol())
241
        return Identifier::fromUid(jsCast<Symbol*>(value)->privateName());
242
    ASSERT(value.isString());
243
    return asString(value)->toIdentifier(lexicalGlobalObject);
244
}
245
246
MessageQueueWaitResult WorkerOrWorkletScriptController::loadModuleSynchronously(LoadableModuleScript& moduleScript, const ScriptSourceCode& sourceCode)
247
{
248
    if (isExecutionForbidden())
249
        return MessageQueueTerminated;
250
251
    initScriptIfNeeded();
252
253
    auto& globalObject = *m_globalScopeWrapper.get();
254
    VM& vm = globalObject.vm();
255
    JSLockHolder lock { vm };
256
257
    auto& promise = JSExecState::loadModule(globalObject, sourceCode.jsSourceCode(), JSC::JSScriptFetcher::create(vm, { &moduleScript }));
258
259
    RefPtr<LoadableModuleScript> moduleScriptRef(&moduleScript);
260
261
    auto& fulfillHandler = *JSNativeStdFunction::create(vm, &globalObject, 1, String(), [moduleScriptRef](JSGlobalObject* globalObject, CallFrame* callFrame) -> JSC::EncodedJSValue {
262
            VM& vm = globalObject->vm();
263
            auto scope = DECLARE_THROW_SCOPE(vm);
264
            Identifier moduleKey = jsValueToModuleKey(globalObject, callFrame->argument(0));
265
            RETURN_IF_EXCEPTION(scope, { });
266
            moduleScriptRef->notifyLoadCompleted(*moduleKey.impl());
267
            return JSValue::encode(jsUndefined());
268
            });
269
270
    auto& rejectHandler = *JSNativeStdFunction::create(vm, &globalObject, 1, String(), [moduleScriptRef](JSGlobalObject* globalObject, CallFrame* callFrame) {
271
            VM& vm = globalObject->vm();
272
            JSValue errorValue = callFrame->argument(0);
273
            if (errorValue.isObject()) {
274
            auto* object = JSC::asObject(errorValue);
275
            if (JSValue failureKindValue = object->getDirect(vm, static_cast<JSVMClientData&>(*vm.clientData).builtinNames().failureKindPrivateName())) {
276
            // This is host propagated error in the module loader pipeline.
277
            switch (static_cast<ModuleFetchFailureKind>(failureKindValue.asInt32())) {
278
            case ModuleFetchFailureKind::WasErrored:
279
            moduleScriptRef->notifyLoadFailed(LoadableScript::Error {
280
                    LoadableScript::ErrorType::CachedScript,
281
                    WTF::nullopt
282
                    });
283
            break;
284
            case ModuleFetchFailureKind::WasCanceled:
285
            moduleScriptRef->notifyLoadWasCanceled();
286
            break;
287
            }
288
            return JSValue::encode(jsUndefined());
289
            }
290
            }
291
292
            auto scope = DECLARE_CATCH_SCOPE(vm);
293
            moduleScriptRef->notifyLoadFailed(LoadableScript::Error {
294
                    LoadableScript::ErrorType::CachedScript,
295
                    LoadableScript::ConsoleMessage {
296
                    MessageSource::JS,
297
                    MessageLevel::Error,
298
                    retrieveErrorMessage(*globalObject, vm, errorValue, scope),
299
                    }
300
                    });
301
            return JSValue::encode(jsUndefined());
302
    });
303
304
    promise.then(&globalObject, &fulfillHandler, &rejectHandler);
305
306
    // Drive RunLoop until we get either of "Worker is terminated", "Loading is done", or "Loading is failed".
307
    WorkerRunLoop& runLoop = m_globalScope->workerOrWorkletThread()->runLoop();
308
    String mode = makeString("loadModuleSynchronously", runLoop.createUniqueId());
309
310
    MessageQueueWaitResult result = MessageQueueMessageReceived;
311
    while ((!moduleScriptRef->isLoaded() || !moduleScriptRef->wasCanceled()) && result != MessageQueueTerminated)
312
        result = runLoop.runInMode(m_globalScope, mode);
313
314
    // FIXME: Currently we are not offering cancelling.
315
    // if (!loader->done() && result == MessageQueueTerminated)
316
    //     loader->cancel();
317
318
    return result;
319
}
320
321
void WorkerOrWorkletScriptController::linkAndEvaluateModule(LoadableModuleScript& moduleScript, const ScriptSourceCode& sourceCode, String* returnedExceptionMessage)
322
{
323
    if (isExecutionForbidden())
324
        return;
325
326
    initScriptIfNeeded();
327
328
    auto& globalObject = *m_globalScopeWrapper.get();
329
    VM& vm = globalObject.vm();
330
    JSLockHolder lock { vm };
331
332
    NakedPtr<JSC::Exception> returnedException;
333
    JSExecState::linkAndEvaluateModule(globalObject, Identifier::fromUid(vm, moduleScript.moduleKey()), jsUndefined(), returnedException);
334
    if ((returnedException && isTerminatedExecutionException(vm, returnedException)) || isTerminatingExecution()) {
335
        forbidExecution();
336
        return;
337
    }
338
339
    if (returnedException) {
340
        if (m_globalScope->canIncludeErrorDetails(sourceCode.cachedScript(), sourceCode.url().string())) {
341
            // FIXME: It's not great that this can run arbitrary code to string-ify the value of the exception.
342
            // Do we need to do anything to handle that properly, if it, say, raises another exception?
343
            if (returnedExceptionMessage)
344
                *returnedExceptionMessage = returnedException->value().toWTFString(&globalObject);
345
        } else {
346
            // Overwrite the detailed error with a generic error.
347
            String genericErrorMessage { "Script error."_s };
348
            if (returnedExceptionMessage)
349
                *returnedExceptionMessage = genericErrorMessage;
350
            returnedException = JSC::Exception::create(vm, createError(&globalObject, genericErrorMessage));
351
        }
352
    }
353
}
354
355
    template<typename JSGlobalScopePrototype, typename JSGlobalScope, typename GlobalScope>
232
void WorkerOrWorkletScriptController::initScriptWithSubclass()
356
void WorkerOrWorkletScriptController::initScriptWithSubclass()
233
{
357
{
234
    ASSERT(!m_globalScopeWrapper);
358
    ASSERT(!m_globalScopeWrapper);
- a/Source/WebCore/workers/WorkerOrWorkletScriptController.h +5 lines
Lines 31-36 a/Source/WebCore/workers/WorkerOrWorkletScriptController.h_sec1
31
#include <JavaScriptCore/JSRunLoopTimer.h>
31
#include <JavaScriptCore/JSRunLoopTimer.h>
32
#include <wtf/Forward.h>
32
#include <wtf/Forward.h>
33
#include <wtf/Lock.h>
33
#include <wtf/Lock.h>
34
#include <wtf/MessageQueue.h>
34
#include <wtf/NakedPtr.h>
35
#include <wtf/NakedPtr.h>
35
36
36
namespace JSC {
37
namespace JSC {
Lines 44-49 class JSGlobalObject; a/Source/WebCore/workers/WorkerOrWorkletScriptController.h_sec2
44
namespace WebCore {
45
namespace WebCore {
45
46
46
class JSDOMGlobalObject;
47
class JSDOMGlobalObject;
48
class LoadableModuleScript;
47
class ScriptSourceCode;
49
class ScriptSourceCode;
48
class WorkerConsoleClient;
50
class WorkerConsoleClient;
49
class WorkerOrWorkletGlobalScope;
51
class WorkerOrWorkletGlobalScope;
Lines 94-99 class WorkerOrWorkletScriptController { a/Source/WebCore/workers/WorkerOrWorkletScriptController.h_sec3
94
    void evaluate(const ScriptSourceCode&, String* returnedExceptionMessage = nullptr);
96
    void evaluate(const ScriptSourceCode&, String* returnedExceptionMessage = nullptr);
95
    void evaluate(const ScriptSourceCode&, NakedPtr<JSC::Exception>& returnedException, String* returnedExceptionMessage = nullptr);
97
    void evaluate(const ScriptSourceCode&, NakedPtr<JSC::Exception>& returnedException, String* returnedExceptionMessage = nullptr);
96
98
99
    void linkAndEvaluateModule(LoadableModuleScript&, const ScriptSourceCode& sourceCode, String* returnedExceptionMessage = nullptr);
100
    MessageQueueWaitResult loadModuleSynchronously(LoadableModuleScript&, const ScriptSourceCode&);
101
97
protected:
102
protected:
98
    WorkerOrWorkletGlobalScope* globalScope() const { return m_globalScope; }
103
    WorkerOrWorkletGlobalScope* globalScope() const { return m_globalScope; }
99
104
- a/Source/WebCore/workers/WorkerThread.cpp -3 / +29 lines
Lines 28-33 a/Source/WebCore/workers/WorkerThread.cpp_sec1
28
#include "WorkerThread.h"
28
#include "WorkerThread.h"
29
29
30
#include "IDBConnectionProxy.h"
30
#include "IDBConnectionProxy.h"
31
#include "LoadableModuleScript.h"
31
#include "ScriptSourceCode.h"
32
#include "ScriptSourceCode.h"
32
#include "SecurityOrigin.h"
33
#include "SecurityOrigin.h"
33
#include "SocketProvider.h"
34
#include "SocketProvider.h"
Lines 55-60 WorkerParameters WorkerParameters::isolatedCopy() const a/Source/WebCore/workers/WorkerThread.cpp_sec2
55
        shouldBypassMainWorldContentSecurityPolicy,
56
        shouldBypassMainWorldContentSecurityPolicy,
56
        timeOrigin,
57
        timeOrigin,
57
        referrerPolicy,
58
        referrerPolicy,
59
        workerType,
60
        credentials,
58
        settingsValues.isolatedCopy()
61
        settingsValues.isolatedCopy()
59
    };
62
    };
60
}
63
}
Lines 123-131 bool WorkerThread::shouldWaitForWebInspectorOnStartup() const a/Source/WebCore/workers/WorkerThread.cpp_sec3
123
126
124
void WorkerThread::evaluateScriptIfNecessary(String& exceptionMessage)
127
void WorkerThread::evaluateScriptIfNecessary(String& exceptionMessage)
125
{
128
{
126
    globalScope()->script()->evaluate(ScriptSourceCode(m_startupData->sourceCode, URL(m_startupData->params.scriptURL)), &exceptionMessage);
129
    // We are currently holding only the initial script code. If the WorkerType is Module, we should fetch the entire graph before executing the rest of this.
127
130
    // We invoke module loader as if we are executing inline module script tag in Document.
128
    finishedEvaluatingScript();
131
132
    if (m_startupData->params.workerType == WorkerType::Classic) {
133
        globalScope()->script()->evaluate(ScriptSourceCode(m_startupData->sourceCode, URL(m_startupData->params.scriptURL)), &exceptionMessage);
134
        finishedEvaluatingScript();
135
    } else {
136
        // FIXME crossOrigin mode should be converted.
137
        // FIXME fix initiator name.
138
        // FIXME pass URL to module loader.
139
        dataLogLn("WORKER MODULE");
140
        ScriptSourceCode sourceCode(m_startupData->sourceCode, URL(m_startupData->params.scriptURL));
141
        auto moduleScript = LoadableModuleScript::create(emptyString(), emptyString(), m_startupData->params.referrerPolicy, ScriptElementCachedScriptFetcher::defaultCrossOriginModeForModule, emptyString(), emptyAtom(), false);
142
        MessageQueueWaitResult result = globalScope()->script()->loadModuleSynchronously(moduleScript.get(), sourceCode);
143
        dataLogLn("WORKER MODULE FETCHED");
144
        if (result != MessageQueueTerminated) {
145
            if (!moduleScript->error() && !moduleScript->wasCanceled()) {
146
                // Evaluate.
147
                globalScope()->script()->linkAndEvaluateModule(moduleScript.get(), sourceCode, &exceptionMessage);
148
                dataLogLn("WORKER MODULE EVALUATED");
149
                finishedEvaluatingScript();
150
            } else {
151
                // FIXME Throw an error.
152
            }
153
        }
154
    }
129
155
130
    // Free the startup data to cause its member variable deref's happen on the worker's thread (since
156
    // Free the startup data to cause its member variable deref's happen on the worker's thread (since
131
    // all ref/derefs of these objects are happening on the thread at this point). Note that
157
    // all ref/derefs of these objects are happening on the thread at this point). Note that
- a/Source/WebCore/workers/WorkerThread.h +5 lines
Lines 26-32 a/Source/WebCore/workers/WorkerThread.h_sec1
26
#pragma once
26
#pragma once
27
27
28
#include "ContentSecurityPolicyResponseHeaders.h"
28
#include "ContentSecurityPolicyResponseHeaders.h"
29
#include "FetchRequestCredentials.h"
29
#include "WorkerOrWorkletThread.h"
30
#include "WorkerOrWorkletThread.h"
31
#include "WorkerRunLoop.h"
32
#include "WorkerType.h"
30
#include <JavaScriptCore/RuntimeFlags.h>
33
#include <JavaScriptCore/RuntimeFlags.h>
31
#include <memory>
34
#include <memory>
32
#include <wtf/URL.h>
35
#include <wtf/URL.h>
Lines 63-68 struct WorkerParameters { a/Source/WebCore/workers/WorkerThread.h_sec2
63
    bool shouldBypassMainWorldContentSecurityPolicy;
66
    bool shouldBypassMainWorldContentSecurityPolicy;
64
    MonotonicTime timeOrigin;
67
    MonotonicTime timeOrigin;
65
    ReferrerPolicy referrerPolicy;
68
    ReferrerPolicy referrerPolicy;
69
    WorkerType workerType;
70
    FetchRequestCredentials credentials;
66
    Settings::Values settingsValues;
71
    Settings::Values settingsValues;
67
72
68
    WorkerParameters isolatedCopy() const;
73
    WorkerParameters isolatedCopy() const;
- a/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp -1 / +2 lines
Lines 73-80 class DummyServiceWorkerThreadProxy : public WorkerObjectProxy { a/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp_sec1
73
// FIXME: Use a valid WorkerObjectProxy
73
// FIXME: Use a valid WorkerObjectProxy
74
// FIXME: Use valid runtime flags
74
// FIXME: Use valid runtime flags
75
75
76
// FIXME: Use a valid WorkerType and Credentails for module service workers.
76
ServiceWorkerThread::ServiceWorkerThread(const ServiceWorkerContextData& data, String&& userAgent, const Settings::Values& settingsValues, WorkerLoaderProxy& loaderProxy, WorkerDebuggerProxy& debuggerProxy, IDBClient::IDBConnectionProxy* idbConnectionProxy, SocketProvider* socketProvider)
77
ServiceWorkerThread::ServiceWorkerThread(const ServiceWorkerContextData& data, String&& userAgent, const Settings::Values& settingsValues, WorkerLoaderProxy& loaderProxy, WorkerDebuggerProxy& debuggerProxy, IDBClient::IDBConnectionProxy* idbConnectionProxy, SocketProvider* socketProvider)
77
    : WorkerThread({ data.scriptURL, emptyString(), "serviceworker:" + Inspector::IdentifiersFactory::createIdentifier(), WTFMove(userAgent), platformStrategies()->loaderStrategy()->isOnLine(), data.contentSecurityPolicy, false, MonotonicTime::now(), { }, settingsValues }, data.script, loaderProxy, debuggerProxy, DummyServiceWorkerThreadProxy::shared(), WorkerThreadStartMode::Normal, data.registration.key.topOrigin().securityOrigin().get(), idbConnectionProxy, socketProvider, JSC::RuntimeFlags::createAllEnabled())
78
    : WorkerThread({ data.scriptURL, emptyString(), "serviceworker:" + Inspector::IdentifiersFactory::createIdentifier(), WTFMove(userAgent), platformStrategies()->loaderStrategy()->isOnLine(), data.contentSecurityPolicy, false, MonotonicTime::now(), { }, WorkerType::Classic, FetchRequestCredentials::SameOrigin, settingsValues }, data.script, loaderProxy, debuggerProxy, DummyServiceWorkerThreadProxy::shared(), WorkerThreadStartMode::Normal, data.registration.key.topOrigin().securityOrigin().get(), idbConnectionProxy, socketProvider, JSC::RuntimeFlags::createAllEnabled())
78
    , m_data(data.isolatedCopy())
79
    , m_data(data.isolatedCopy())
79
    , m_workerObjectProxy(DummyServiceWorkerThreadProxy::shared())
80
    , m_workerObjectProxy(DummyServiceWorkerThreadProxy::shared())
80
    , m_heartBeatTimeout(SWContextManager::singleton().connection()->shouldUseShortTimeout() ? heartBeatTimeoutForTest : heartBeatTimeout)
81
    , m_heartBeatTimeout(SWContextManager::singleton().connection()->shouldUseShortTimeout() ? heartBeatTimeoutForTest : heartBeatTimeout)

Return to Bug 164860