Changeset 292799 in webkit
- Timestamp:
- Apr 12, 2022 9:27:16 PM (3 months ago)
- Location:
- trunk
- Files:
-
- 1 added
- 19 edited
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/wasm/webapi/esm-integration/resources/worker-helper.js (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/wasm/webapi/esm-integration/worker-import.tentative-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/wasm/webapi/esm-integration/worker-import.tentative.html (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (2 diffs)
-
Source/WebCore/bindings/js/ScriptBufferSourceProvider.h (modified) (2 diffs)
-
Source/WebCore/bindings/js/ScriptModuleLoader.cpp (modified) (2 diffs)
-
Source/WebCore/bindings/js/WebAssemblyScriptBufferSourceProvider.h (added)
-
Source/WebCore/bindings/js/WebAssemblyScriptSourceCode.h (modified) (2 diffs)
-
Source/WebCore/workers/ScriptBuffer.cpp (modified) (1 diff)
-
Source/WebCore/workers/ScriptBuffer.h (modified) (1 diff)
-
Source/WebCore/workers/WorkerEventLoop.cpp (modified) (2 diffs)
-
Source/WebCore/workers/WorkerEventLoop.h (modified) (1 diff)
-
Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp (modified) (1 diff)
-
Source/WebCore/workers/WorkerOrWorkletGlobalScope.h (modified) (1 diff)
-
Source/WebCore/workers/WorkerOrWorkletScriptController.cpp (modified) (1 diff)
-
Source/WebCore/workers/WorkerRunLoop.cpp (modified) (8 diffs)
-
Source/WebCore/workers/WorkerRunLoop.h (modified) (3 diffs)
-
Source/WebCore/workers/WorkerScriptLoader.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r292759 r292799 1 2022-04-12 Asumu Takikawa <asumu@igalia.com> 2 3 Allow Wasm import from a JS Worker module 4 https://bugs.webkit.org/show_bug.cgi?id=238291 5 6 Reviewed by Yusuke Suzuki. 7 8 Fixed worker test and updated expectation. 9 10 * web-platform-tests/wasm/webapi/esm-integration/resources/worker-helper.js: 11 (export.pm): 12 * web-platform-tests/wasm/webapi/esm-integration/worker-import.tentative-expected.txt: 13 * web-platform-tests/wasm/webapi/esm-integration/worker-import.tentative.html: 14 1 15 2022-04-11 Antti Koivisto <antti@apple.com> 2 16 -
trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/webapi/esm-integration/resources/worker-helper.js
r290300 r292799 1 export const pm = DedicatedWorkerGlobalScope.postMessage;1 export function pm(x) { postMessage(x); } -
trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/webapi/esm-integration/worker-import.tentative-expected.txt
r290300 r292799 1 CONSOLE MESSAGE: TypeError: WebAssembly modules are not supported in workers yet.2 1 3 FAIL Testing import of WebAssembly from JavaScript worker Script error. 2 PASS Testing import of WebAssembly from JavaScript worker 4 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/webapi/esm-integration/worker-import.tentative.html
r290300 r292799 8 8 const worker = new Worker("resources/worker.js", { type: "module" }); 9 9 worker.onmessage = (msg) => { 10 assert_equals(msg , 42);10 assert_equals(msg.data, 42); 11 11 done(); 12 12 } -
trunk/Source/WebCore/ChangeLog
r292797 r292799 1 2022-04-12 Asumu Takikawa <asumu@igalia.com> 2 3 Allow Wasm import from a JS Worker module 4 https://bugs.webkit.org/show_bug.cgi?id=238291 5 6 Reviewed by Yusuke Suzuki. 7 8 Adds new source provider for Wasm module loading when imported via 9 a JS module running in a Worker. Also adjust how WorkerRunLoop 10 processes tasks for script module loading. In particular, during 11 the module parsing phase, Wasm modules schedule async tasks that 12 need to be run to produce a module record. 13 14 When a Wasm module is loaded (via the module loader's module parsing 15 step), the validation/compilation happens asynchronously and 16 completion callbacks are run via 17 DeferredWorkTimer::scheduleWorkSoon, which queues up microtasks 18 from the VM. These microtasks, however, don't get run in a Worker 19 run loop during module loading and therefore the Wasm module never 20 finishes loading. 21 22 This is because during non-default modes, the Worker run loop 23 does not install its set timer callback, and continues to wait for 24 a task to run (due to infinite timeout). This means the microtask 25 checkpoint is also not reached, so other microtasks cannot run. 26 In non-default modes, the run loop also ignores all tasks that were 27 not installed in that particular mode. 28 29 In addition, the Worker event loop cannot run either, as it posts 30 default mode tasks to the run loop to trigger its operation. 31 32 The current patch modifies the run loop to allow the run loop to time 33 out even in non-default modes if a `useTimeout` parameter is passed as 34 true (defaults to false). We set this to true for the Worker module 35 loading process. It also allows the timer notification callback to 36 post tasks to non-default run loops. 37 38 * WebCore.xcodeproj/project.pbxproj: 39 * bindings/js/ScriptBufferSourceProvider.h: 40 (WebCore::AbstractScriptBufferHolder::~AbstractScriptBufferHolder): 41 * bindings/js/ScriptModuleLoader.cpp: 42 (WebCore::ScriptModuleLoader::notifyFinished): 43 * bindings/js/WebAssemblyScriptBufferSourceProvider.h: Added. 44 * bindings/js/WebAssemblyScriptSourceCode.h: 45 (WebCore::WebAssemblyScriptSourceCode::WebAssemblyScriptSourceCode): 46 * workers/ScriptBuffer.cpp: 47 (WebCore::ScriptBuffer::append): 48 * workers/ScriptBuffer.h: 49 * workers/WorkerEventLoop.cpp: 50 (WebCore::WorkerEventLoop::scheduleToRun): 51 (WebCore::WorkerEventLoop::taskMode): 52 * workers/WorkerEventLoop.h: 53 * workers/WorkerOrWorkletGlobalScope.cpp: 54 (WebCore::WorkerOrWorkletGlobalScope::postTaskForMode): 55 * workers/WorkerOrWorkletGlobalScope.h: 56 * workers/WorkerOrWorkletScriptController.cpp: 57 (WebCore::WorkerOrWorkletScriptController::loadModuleSynchronously): 58 * workers/WorkerRunLoop.cpp: 59 (WebCore::ModePredicate::ModePredicate): 60 (WebCore::ModePredicate::mode const): 61 (WebCore::ModePredicate::operator() const): 62 (WebCore::WorkerDedicatedRunLoop::run): 63 (WebCore::WorkerDedicatedRunLoop::runInDebuggerMode): 64 (WebCore::WorkerDedicatedRunLoop::runInMode): 65 (WebCore::WorkerMainRunLoop::runInMode): 66 * workers/WorkerRunLoop.h: 67 * workers/WorkerScriptLoader.cpp: 68 (WebCore::WorkerScriptLoader::didReceiveData): 69 1 70 2022-04-12 Elliott Williams <emw@apple.com> 2 71 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r292780 r292799 10261 10261 550F664522CA89BD000A3417 /* SVGSharedPrimitiveProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGSharedPrimitiveProperty.h; sourceTree = "<group>"; }; 10262 10262 55137B2C20379E550001004B /* SVGMarkerTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGMarkerTypes.h; sourceTree = "<group>"; }; 10263 5523B98B27ED194800ECA746 /* WebAssemblyScriptBufferSourceProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebAssemblyScriptBufferSourceProvider.h; path = bindings/js/WebAssemblyScriptBufferSourceProvider.h; sourceTree = "<group>"; }; 10263 10264 554675771FD1FC1A003B10B0 /* ImageSource.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageSource.cpp; sourceTree = "<group>"; }; 10264 10265 554675781FD1FC1A003B10B0 /* ImageSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageSource.h; sourceTree = "<group>"; }; … … 19028 19029 isa = PBXGroup; 19029 19030 children = ( 19031 5523B98B27ED194800ECA746 /* WebAssemblyScriptBufferSourceProvider.h */, 19030 19032 DDB04F37278E5527008D3678 /* libWTF.a */, 19031 19033 1C09D04B1E31C32800725F18 /* PAL.xcodeproj */, -
trunk/Source/WebCore/bindings/js/ScriptBufferSourceProvider.h
r287021 r292799 32 32 namespace WebCore { 33 33 34 class ScriptBufferSourceProvider final : public JSC::SourceProvider, public CanMakeWeakPtr<ScriptBufferSourceProvider> { 34 class AbstractScriptBufferHolder : public CanMakeWeakPtr<AbstractScriptBufferHolder> { 35 public: 36 virtual void clearDecodedData() = 0; 37 virtual void tryReplaceScriptBuffer(const ScriptBuffer&) = 0; 38 39 virtual ~AbstractScriptBufferHolder() { } 40 }; 41 42 class ScriptBufferSourceProvider final : public JSC::SourceProvider, public AbstractScriptBufferHolder { 35 43 WTF_MAKE_FAST_ALLOCATED; 36 44 public: … … 71 79 } 72 80 73 void clearDecodedData() 81 void clearDecodedData() final 74 82 { 75 83 m_cachedScriptString = String(); 76 84 } 77 85 78 void tryReplaceScriptBuffer(const ScriptBuffer& scriptBuffer) 86 void tryReplaceScriptBuffer(const ScriptBuffer& scriptBuffer) final 79 87 { 80 88 // If this new file-mapped script buffer is identical to the one we have, then replace -
trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp
r292118 r292799 483 483 type = ModuleType::JavaScript; 484 484 #if ENABLE(WEBASSEMBLY) 485 else if (context().settingsValues().webAssemblyESMIntegrationEnabled && MIMETypeRegistry::isSupportedWebAssemblyMIMEType(loader.responseMIMEType())) {485 else if (context().settingsValues().webAssemblyESMIntegrationEnabled && MIMETypeRegistry::isSupportedWebAssemblyMIMEType(loader.responseMIMEType())) 486 486 type = ModuleType::WebAssembly; 487 // FIXME: add worker support for Wasm/ESM integration.488 rejectWithFetchError(promise.get(), TypeError, makeString("WebAssembly modules are not supported in workers yet."));489 return;490 }491 487 #endif 492 488 else { … … 519 515 JSC::SourceCode { ScriptSourceCode { loader.script(), WTFMove(responseURL), { }, JSC::SourceProviderSourceType::Module, loader.scriptFetcher() }.jsSourceCode() }); 520 516 break; 517 #if ENABLE(WEBASSEMBLY) 521 518 case ModuleType::WebAssembly: 519 return JSC::JSSourceCode::create(jsGlobalObject.vm(), 520 JSC::SourceCode { WebAssemblyScriptSourceCode { loader.script(), WTFMove(responseURL), loader.scriptFetcher() }.jsSourceCode() }); 521 break; 522 #endif 522 523 default: 523 524 RELEASE_ASSERT_NOT_REACHED(); -
trunk/Source/WebCore/bindings/js/WebAssemblyScriptSourceCode.h
r290300 r292799 33 33 #include "SharedBuffer.h" 34 34 #include "WebAssemblyCachedScriptSourceProvider.h" 35 #include "WebAssemblyScriptBufferSourceProvider.h" 35 36 #include <JavaScriptCore/SourceCode.h> 36 37 #include <JavaScriptCore/SourceProvider.h> … … 49 50 } 50 51 52 WebAssemblyScriptSourceCode(const ScriptBuffer& source, URL&& url, Ref<JSC::ScriptFetcher>&& scriptFetcher) 53 : m_provider(WebAssemblyScriptBufferSourceProvider::create(source, WTFMove(url), WTFMove(scriptFetcher))) 54 , m_code(m_provider.copyRef()) 55 { 56 } 57 51 58 const JSC::SourceCode& jsSourceCode() const { return m_code; } 52 59 -
trunk/Source/WebCore/workers/ScriptBuffer.cpp
r286983 r292799 70 70 } 71 71 72 void ScriptBuffer::append(const FragmentedSharedBuffer& buffer) 73 { 74 m_buffer.append(buffer); 75 } 76 72 77 bool operator==(const ScriptBuffer& a, const ScriptBuffer& b) 73 78 { -
trunk/Source/WebCore/workers/ScriptBuffer.h
r287021 r292799 57 57 WEBCORE_EXPORT bool containsSingleFileMappedSegment() const; 58 58 void append(const String&); 59 void append(const FragmentedSharedBuffer&); 59 60 60 61 private: -
trunk/Source/WebCore/workers/WorkerEventLoop.cpp
r282755 r292799 48 48 void WorkerEventLoop::scheduleToRun() 49 49 { 50 ASSERT(scriptExecutionContext()); 51 scriptExecutionContext()->postTask([eventLoop = Ref { *this }] (ScriptExecutionContext&) { 50 auto* globalScope = downcast<WorkerOrWorkletGlobalScope>(scriptExecutionContext()); 51 ASSERT(globalScope); 52 // Post this task with a special event mode, so that it can be separated from other 53 // kinds of tasks so that queued microtasks can run even if other tasks are ignored. 54 globalScope->postTaskForMode([eventLoop = Ref { *this }] (ScriptExecutionContext&) { 52 55 eventLoop->run(); 53 } );56 }, WorkerEventLoop::taskMode()); 54 57 } 55 58 … … 72 75 } 73 76 77 const String WorkerEventLoop::taskMode() 78 { 79 return "workerEventLoopTaskMode"_s; 80 } 81 74 82 } // namespace WebCore 75 -
trunk/Source/WebCore/workers/WorkerEventLoop.h
r268822 r292799 39 39 virtual ~WorkerEventLoop(); 40 40 41 static const String taskMode(); 41 42 // FIXME: This should be removed once MicrotaskQueue is integrated with EventLoopTaskGroup. 42 43 void clearMicrotaskQueue(); -
trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp
r284226 r292799 121 121 } 122 122 123 void WorkerOrWorkletGlobalScope::postTaskForMode(Task&& task, const String& mode) 124 { 125 ASSERT(workerOrWorkletThread()); 126 workerOrWorkletThread()->runLoop().postTaskForMode(WTFMove(task), mode); 127 } 128 123 129 } // namespace WebCore -
trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h
r289721 r292799 66 66 void postTask(Task&&) final; // Executes the task on context's thread asynchronously. 67 67 68 // Defined specifcially for WorkerOrWorkletGlobalScope for cooperation with 69 // WorkerEventLoop and WorkerRunLoop, not part of ScriptExecutionContext. 70 void postTaskForMode(Task&&, const String&); 71 68 72 virtual void prepareForDestruction(); 69 73 -
trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp
r290300 r292799 365 365 // in the following driving of the RunLoop which mainly attempt to collect initial load of module scripts. 366 366 String taskMode = WorkerModuleScriptLoader::taskMode(); 367 368 // Allow tasks scheduled from the WorkerEventLoop. 369 constexpr bool allowEventLoopTasks = true; 370 367 371 bool success = true; 368 372 while ((!protector->isLoaded() && !protector->wasCanceled()) && success) { 369 success = runLoop.runInMode(m_globalScope, taskMode );373 success = runLoop.runInMode(m_globalScope, taskMode, allowEventLoopTasks); 370 374 if (success) 371 375 m_globalScope->eventLoop().performMicrotaskCheckpoint(); -
trunk/Source/WebCore/workers/WorkerRunLoop.cpp
r284857 r292799 37 37 #include "ThreadGlobalData.h" 38 38 #include "ThreadTimers.h" 39 #include "WorkerEventLoop.h" 39 40 #include "WorkerOrWorkletGlobalScope.h" 40 41 #include "WorkerOrWorkletScriptController.h" … … 66 67 class ModePredicate { 67 68 public: 68 explicit ModePredicate(String&& mode )69 explicit ModePredicate(String&& mode, bool allowEventLoopTasks) 69 70 : m_mode(WTFMove(mode)) 70 71 , m_defaultMode(m_mode == WorkerRunLoop::defaultMode()) 71 { 72 , m_allowEventLoopTasks(allowEventLoopTasks) 73 { 74 } 75 76 const String mode() const 77 { 78 return m_mode; 72 79 } 73 80 … … 79 86 bool operator()(const WorkerDedicatedRunLoop::Task& task) const 80 87 { 81 return m_defaultMode || m_mode == task.mode() ;88 return m_defaultMode || m_mode == task.mode() || (m_allowEventLoopTasks && task.mode() == WorkerEventLoop::taskMode()); 82 89 } 83 90 … … 85 92 String m_mode; 86 93 bool m_defaultMode; 94 bool m_allowEventLoopTasks; 87 95 }; 88 96 … … 138 146 { 139 147 RunLoopSetup setup(*this, RunLoopSetup::IsForDebugging::No); 140 ModePredicate modePredicate(defaultMode() );148 ModePredicate modePredicate(defaultMode(), false); 141 149 MessageQueueWaitResult result; 142 150 do { … … 149 157 { 150 158 RunLoopSetup setup(*this, RunLoopSetup::IsForDebugging::Yes); 151 return runInMode(&context, ModePredicate { debuggerMode() });152 } 153 154 bool WorkerDedicatedRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const String& mode )159 return runInMode(&context, ModePredicate { debuggerMode(), false }); 160 } 161 162 bool WorkerDedicatedRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const String& mode, bool allowEventLoopTasks) 155 163 { 156 164 ASSERT(mode != debuggerMode()); 157 165 RunLoopSetup setup(*this, RunLoopSetup::IsForDebugging::No); 158 ModePredicate modePredicate(String { mode } );166 ModePredicate modePredicate(String { mode }, allowEventLoopTasks); 159 167 return runInMode(context, modePredicate) != MessageQueueWaitResult::MessageQueueTerminated; 160 168 } … … 165 173 ASSERT(context->workerOrWorkletThread()->thread() == &Thread::current()); 166 174 167 JSC::JSRunLoopTimer::TimerNotificationCallback timerAddedTask = createSharedTask<JSC::JSRunLoopTimer::TimerNotificationType>([this] { 175 const String predicateMode = predicate.mode(); 176 JSC::JSRunLoopTimer::TimerNotificationCallback timerAddedTask = createSharedTask<JSC::JSRunLoopTimer::TimerNotificationType>([this, predicateMode] { 168 177 // We don't actually do anything here, we just want to loop around runInMode 169 178 // to both recalculate our deadline and to potentially run the run loop. 170 this->postTask ([](ScriptExecutionContext&) { });179 this->postTaskForMode([predicateMode](ScriptExecutionContext&) { }, predicateMode); 171 180 }); 172 181 … … 312 321 } 313 322 314 bool WorkerMainRunLoop::runInMode(WorkerOrWorkletGlobalScope*, const String& )323 bool WorkerMainRunLoop::runInMode(WorkerOrWorkletGlobalScope*, const String&, bool) 315 324 { 316 325 RunLoop::main().cycle(); -
trunk/Source/WebCore/workers/WorkerRunLoop.h
r283295 r292799 49 49 virtual ~WorkerRunLoop() = default; 50 50 51 virtual bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode ) = 0;51 virtual bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode, bool allowEventLoopTasks = false) = 0; 52 52 virtual void postTaskAndTerminate(ScriptExecutionContext::Task&&) = 0; 53 53 virtual void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode) = 0; … … 76 76 77 77 // Waits for a single task and returns. 78 bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode ) final;78 bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode, bool) final; 79 79 MessageQueueWaitResult runInDebuggerMode(WorkerOrWorkletGlobalScope&); 80 80 … … 126 126 bool terminated() const final { return m_terminated; } 127 127 128 bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode );128 bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode, bool); 129 129 void postTaskAndTerminate(ScriptExecutionContext::Task&&) final; 130 130 void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode) final; -
trunk/Source/WebCore/workers/WorkerScriptLoader.cpp
r291992 r292799 235 235 return; 236 236 237 #if ENABLE(WEBASSEMBLY) 238 if (MIMETypeRegistry::isSupportedWebAssemblyMIMEType(m_responseMIMEType)) { 239 m_script.append(buffer); 240 return; 241 } 242 #endif 243 237 244 if (!m_decoder) 238 245 m_decoder = TextResourceDecoder::create("text/javascript"_s, "UTF-8");
Note: See TracChangeset
for help on using the changeset viewer.