RESOLVED FIXED Bug 173105
WebAssembly: add support for stream APIs
https://bugs.webkit.org/show_bug.cgi?id=173105
Summary WebAssembly: add support for stream APIs
JF Bastien
Reported 2017-06-08 09:57:55 PDT
Post-MVP APIs were added: https://github.com/WebAssembly/design/blob/master/Web.md#additional-web-embedding-api WebAssembly.compileStreaming WebAssembly.instantiateStreaming
Attachments
Patch (23.54 KB, patch)
2018-01-03 12:00 PST, GSkachkov
no flags
WASM and CSP test cases. (13.97 KB, application/zip)
2019-05-10 14:58 PDT, Rob
no flags
Patch (33.67 KB, patch)
2021-01-25 14:03 PST, Yusuke Suzuki
ews-feeder: commit-queue-
Patch (228.41 KB, patch)
2021-01-25 22:54 PST, Yusuke Suzuki
ews-feeder: commit-queue-
Patch (270.10 KB, patch)
2021-01-26 01:19 PST, Yusuke Suzuki
no flags
Patch (230.85 KB, patch)
2021-01-26 01:49 PST, Yusuke Suzuki
no flags
Patch (238.29 KB, patch)
2021-01-26 03:40 PST, Yusuke Suzuki
no flags
Patch (239.25 KB, patch)
2021-01-26 16:44 PST, Yusuke Suzuki
no flags
Patch (339.99 KB, patch)
2021-01-26 19:54 PST, Yusuke Suzuki
no flags
Patch (345.80 KB, patch)
2021-01-26 21:24 PST, Yusuke Suzuki
no flags
Patch (345.80 KB, patch)
2021-01-26 21:25 PST, Yusuke Suzuki
no flags
Patch (345.98 KB, patch)
2021-01-26 21:31 PST, Yusuke Suzuki
ews-feeder: commit-queue-
Patch (346.23 KB, patch)
2021-01-26 21:33 PST, Yusuke Suzuki
no flags
Patch (340.66 KB, patch)
2021-01-27 14:40 PST, Yusuke Suzuki
keith_miller: review+
JF Bastien
Comment 1 2017-06-08 09:58:43 PDT
I think this is fairly low priority. When we do it we should make sure we actually stream-compile, not just download all and then start compilation.
JF Bastien
Comment 2 2017-06-29 10:58:47 PDT
When implementing this, don't forget to test CSP. I added a FIXME in 173892. This will be trickier than current wasm CSP because the streaming APIs refer to URLs, not just array buffers. Also consider what we do for SRI.
GSkachkov
Comment 3 2017-12-17 01:00:34 PST
Can I take this task? I will have free time so possible I'll manage implement this.
JF Bastien
Comment 4 2017-12-17 08:05:24 PST
Sure.
GSkachkov
Comment 5 2018-01-03 12:00:28 PST
Created attachment 330407 [details] Patch WiP. Link WebCore and JSC, and handle response from fetch. Next steps: Implement streaming parsing, run parsing in separate thread, CSP&SPI
JF Bastien
Comment 6 2018-02-20 16:10:38 PST
Comment on attachment 330407 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=330407&action=review A few comments to start. > Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp:114 > +void WebAssemblyPrototype::webAssemblyModuleValidateAsync(ExecState* exec, Vector<uint8_t>&& source, JSPromiseDeferred* promise) This and the internal one can just be file-level static functions. > Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp:120 > + RETURN_IF_EXCEPTION(throwScope, void()); I don't think this makes sense here? > Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp:156 > + RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined())); Ditto. > Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp:170 > + promise->reject(exec, createTypeError(exec, ASCIILiteral("CompileStreaming is not supported in jsc, only in browser environment."))); I might be wrong, but I think compileStreaming can take a blob URL? In that case it probably should work in JSC. What do other streaming things do in JSC? > Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp:291 > + } else { Add a FIXME here: if there's an importObject and it contains a Memory, then we can compile the module with the right memory type (fast or not) by looking at the memory's type. > Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp:296 > + compileAndInstantiate(vm, exec, promise, firstArgument, importObject); The above 4 lines seem wrong per spec: https://www.w3.org/TR/2018/WD-wasm-web-api-1-20180215/#streaming-modules > Source/WebCore/bindings/js/JSDOMWindowBase.cpp:391 > + promise->reject(exec, createTypeError(exec, ASCIILiteral("first argument must be an Response or Promise for Response #5"))); This doesn't seem like the right error message for an OOM condition. > Source/WebCore/bindings/js/JSDOMWindowBase.cpp:402 > + // TODO: Implement CSP and SPI check before start consume content from Response I think you mean SRI.
GSkachkov
Comment 7 2018-03-08 03:20:40 PST
Thanks for review!!! During the implementation this feature, I see that is more complicated that I expected, so I split it into 3 tasks: 1) Just adding javascript API, but without streaming compilation: * WebAssembly.compileStreaming * WebAssembly.instantiateStreaming 2) Streaming compilation, compile and verify as soon as wasm chunk is delivered over network 3) Implement allow to compile each function in separate thread. So I hope it allow to decrease size and complexity of the patches
Rob
Comment 25 2019-05-09 16:52:58 PDT
It seems that development here has stalled. We would love to see this added, but the purpose of this comment is to verify that the stream APIs will properly support origins and SRI hashes in CSPs. The comments here seem to indicate that that is a priority, but it's not super clear. Here is a proposal that discusses the appropriate behavior of these functions: https://github.com/WebAssembly/content-security-policy/blob/master/proposals/CSP.md#proposed-origin-bound-permission Ideally SRI hashes would be supported by the other WebAssembly APIs as well, but getting the stream APIs right from the beginning would be a huge win.
Rob
Comment 26 2019-05-10 14:58:14 PDT
Created attachment 369602 [details] WASM and CSP test cases. Here is a set of tests and a summary of major browser behavior.
Adam Klein
Comment 27 2019-12-10 16:47:34 PST
Any updates here?
Radar WebKit Bug Importer
Comment 28 2019-12-15 02:59:19 PST
Maksim Nesterenko
Comment 29 2020-08-18 02:25:36 PDT
Hello, is there any plans on adding this?
Yusuke Suzuki
Comment 30 2020-09-01 10:26:41 PDT
This is currently planned in my TODO tasks :)
Maksim Nesterenko
Comment 31 2020-09-02 00:11:52 PDT
Okay, I'm really looking forward to it :) Currently, it's a huge lack of support because without instantiateStreaming it's impossible to use wasm under environments with content security policies (where usually unsafe-eval is blocked).
Kenneth Russell
Comment 32 2020-12-23 11:21:08 PST
Eagerly looking forward to this too - Google Meet's background blur feature uses WebAssembly.instantiateStreaming, so adding this would get it one step closer to running in Safari!
styfle
Comment 33 2021-01-19 16:51:35 PST
Looking forward to this feature as well! Currently, wasm-bindgen generates a lot of boilerplate to support Safari, which is the only browser that doesn't support WebAssembly.instantiateStreaming(). References: https://github.com/rustwasm/wasm-bindgen https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming#browser_compatibility
Yusuke Suzuki
Comment 34 2021-01-25 14:00:57 PST
*** Bug 184888 has been marked as a duplicate of this bug. ***
Yusuke Suzuki
Comment 35 2021-01-25 14:02:23 PST
*** Bug 183444 has been marked as a duplicate of this bug. ***
Yusuke Suzuki
Comment 36 2021-01-25 14:02:31 PST
*** Bug 183443 has been marked as a duplicate of this bug. ***
Yusuke Suzuki
Comment 37 2021-01-25 14:02:41 PST
*** Bug 184886 has been marked as a duplicate of this bug. ***
Yusuke Suzuki
Comment 38 2021-01-25 14:03:09 PST
Yusuke Suzuki
Comment 39 2021-01-25 22:54:10 PST
Yusuke Suzuki
Comment 40 2021-01-26 01:19:52 PST
Yusuke Suzuki
Comment 41 2021-01-26 01:49:54 PST
Yusuke Suzuki
Comment 42 2021-01-26 03:40:58 PST
EWS Watchlist
Comment 43 2021-01-26 03:42:01 PST
This patch modifies the imported WPT tests. Please ensure that any changes on the tests (not coming from a WPT import) are exported to WPT. Please see https://trac.webkit.org/wiki/WPTExportProcess
Yusuke Suzuki
Comment 44 2021-01-26 16:44:26 PST
Yusuke Suzuki
Comment 45 2021-01-26 19:54:30 PST
Yusuke Suzuki
Comment 46 2021-01-26 21:24:03 PST
Yusuke Suzuki
Comment 47 2021-01-26 21:25:57 PST
Yusuke Suzuki
Comment 48 2021-01-26 21:31:15 PST
Yusuke Suzuki
Comment 49 2021-01-26 21:33:47 PST
Yusuke Suzuki
Comment 50 2021-01-27 14:40:08 PST
Keith Miller
Comment 51 2021-01-27 15:13:34 PST
Comment on attachment 418585 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=418585&action=review r=me with some comments. > Source/JavaScriptCore/wasm/WasmStreamingCompiler.cpp:89 > + ensureWorklist().enqueue(WTFMove(plan)); Wait, why does the ChangeLog say you don't use the WasmWorklist? is `ensureWorklist()` not the Wasm one? > Source/JavaScriptCore/wasm/WasmStreamingCompiler.cpp:139 > + auto* promise = std::exchange(m_promise, nullptr); Why is this needed? Isn't the promise retained by the DeferredWorkTimer? > Source/JavaScriptCore/wasm/WasmStreamingPlan.h:53 > + // For some reason friendship doesn't extend to parent classes... Heh, I read this and thought to myself... This doesn't seem like something Yusuke would right. Turns out I wrote it and you copied it here, lol > Source/WebCore/bindings/js/JSDOMGlobalObject.cpp:319 > + bool isResponseCorsSameOrigin = inputResponse->type() == ResourceResponse::Type::Basic || inputResponse->type() == ResourceResponse::Type::Cors || inputResponse->type() == ResourceResponse::Type::Default; I feel like this should be a member function on JSFetchResponse. It's a bit magical here but wouldn't need a comment if the condition of the if was `if (inputResponse->isCorsSameOrigin())` > Source/WebCore/bindings/js/JSDOMGlobalObject.cpp:326 > + auto contentType = inputResponse->headers().fastGet(HTTPHeaderName::ContentType); Ditto but less important. > Source/WebCore/bindings/js/JSDOMGlobalObject.cpp:347 > + inputResponse->consumeBodyReceivedByChunk([globalObject, compiler = WTFMove(compiler)](auto&& result) mutable { Does this happen on the main thread out of curiosity or can it happen elsewhere?
Yusuke Suzuki
Comment 52 2021-01-27 15:54:10 PST
Comment on attachment 418585 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=418585&action=review >> Source/JavaScriptCore/wasm/WasmStreamingCompiler.cpp:89 >> + ensureWorklist().enqueue(WTFMove(plan)); > > Wait, why does the ChangeLog say you don't use the WasmWorklist? is `ensureWorklist()` not the Wasm one? LLIntPlan is not using Worklist. Instead, we generate StreamingPlan one per one wasm function, and they are enqueued into worklist. I'll add more description in ChangeLog. >> Source/JavaScriptCore/wasm/WasmStreamingCompiler.cpp:139 >> + auto* promise = std::exchange(m_promise, nullptr); > > Why is this needed? Isn't the promise retained by the DeferredWorkTimer? Just make sure that m_promise is nullptr after scheduling deferredWorkTimer resolution. This also allows the destructor to ensure that scheduled task is resolved by checking `m_promise`. >> Source/JavaScriptCore/wasm/WasmStreamingPlan.h:53 >> + // For some reason friendship doesn't extend to parent classes... > > Heh, I read this and thought to myself... This doesn't seem like something Yusuke would right. Turns out I wrote it and you copied it here, lol Yeah, I copied it from OMGPlan since both shares the idea "compile one function at a time". >> Source/WebCore/bindings/js/JSDOMGlobalObject.cpp:319 >> + bool isResponseCorsSameOrigin = inputResponse->type() == ResourceResponse::Type::Basic || inputResponse->type() == ResourceResponse::Type::Cors || inputResponse->type() == ResourceResponse::Type::Default; > > I feel like this should be a member function on JSFetchResponse. It's a bit magical here but wouldn't need a comment if the condition of the if was `if (inputResponse->isCorsSameOrigin())` Sounds nice! Changed. >> Source/WebCore/bindings/js/JSDOMGlobalObject.cpp:326 >> + auto contentType = inputResponse->headers().fastGet(HTTPHeaderName::ContentType); > > Ditto but less important. Sounds nice, changed. >> Source/WebCore/bindings/js/JSDOMGlobalObject.cpp:347 >> + inputResponse->consumeBodyReceivedByChunk([globalObject, compiler = WTFMove(compiler)](auto&& result) mutable { > > Does this happen on the main thread out of curiosity or can it happen elsewhere? This is under the main thread. Invoked via didReceiveData callback from Fetch's BodyLoader.
Yusuke Suzuki
Comment 53 2021-01-27 15:58:41 PST
*** Bug 170511 has been marked as a duplicate of this bug. ***
Yusuke Suzuki
Comment 54 2021-01-27 17:31:41 PST
Note You need to log in before you can comment on or make changes to this bug.