RESOLVED WONTFIX 265151
`WebAssembly` is no longer part of the global object
https://bugs.webkit.org/show_bug.cgi?id=265151
Summary `WebAssembly` is no longer part of the global object
Ivan Enderlin
Reported 2023-11-20 10:40:32 PST
Hi, Before the update to macOS 14 (Sonoma), `WebAssembly` was defined on the global object (from a `JSContext` + `JSContextGetGlobalObject` + `JSObjectGetProperty`). Since the update, `WebAssembly` is undefined. Worst: evaluating the following simple script `const wasm = WebAssembly.Instance` makes the process crash with a SIGSEGV. It seems to affect macOS and iOS (the latter must be confirmed). I'm using XCode 15. I'm also using the JavaScriptCore bundled framework, with the C API. Is it normal? Is it expected? I didn't see any announcement or anything particular. It's a blocker because it's a breaking change. Thanks for your help.
Attachments
Test case (1.13 KB, text/x-csrc)
2023-11-20 20:47 PST, Ross Kirsling
no flags
Ivan Enderlin
Comment 1 2023-11-20 10:46:48 PST
Karl Dubost
Comment 2 2023-11-20 14:33:41 PST
Thanks Ivan. Maybe Justin will have something to say about this.
Radar WebKit Bug Importer
Comment 3 2023-11-20 14:33:51 PST
Karl Dubost
Comment 4 2023-11-20 14:35:32 PST
A clear simple testcase should be added to this bug report.
Ross Kirsling
Comment 5 2023-11-20 17:35:25 PST
(Note that bug 263763 is not relevant here; the patch that was ultimately landed there, 270100@main, just made it possible to pass --useWebAssembly=1 when JIT is off.)
Ross Kirsling
Comment 6 2023-11-20 20:47:14 PST
Created attachment 468698 [details] Test case Hmm, I'm not managing to reproduce this on an Intel MBP with Sonoma 14.1.1 (Safari 17.1, Xcode 15.0.1). The attached test file does what was described in the bug report, namely: 1. get WebAssembly property on global object and verify it's an object with an Instance property 2. execute the one-line script `const wasm = WebAssembly.Instance;` Compiling this with the following command produces an executable which works as expected: > clang++ -framework JavaScriptCore -std=c++20 -o ./main wasm-test.cpp It also works via Xcode, by setting up a Command Line Tool project which depends on JavaScriptCore.framework.
Ivan Enderlin
Comment 7 2023-11-20 23:30:59 PST
Thanks Ross for your test case. I've modified line 11 to: ```cpp assert(!exception); assert(JSValueIsObject(globalContext, wasmValue)); ``` Running the script if your command-line: ```shell $ clang++ -framework JavaScriptCore -std=c++20 -o ./wasm-test wasm-test.cp $ ./wasm-test Assertion failed: (JSValueIsObject(globalContext, wasmValue)), function main, file wasm-test.cpp, line 12. ``` I've added this new assertion before line 11: ```cpp assert(JSValueIsUndefined(globalContext, wasmValue)); ``` and it passes. So `wasmValue` is indeed undefined, and… `WebAssembly` isn't a property of the global object. I'm using macOS Sonoma 14.1.1 (23B81) if that helps, on a MacBook Pro M1.
Ivan Enderlin
Comment 8 2023-11-21 00:01:09 PST
Someone else has tried this test program on macOS Sonoma, but on x86_64, and it works, just like for Ross. It seems to be an issue on aarch64 only. Maybe.
Ross Kirsling
Comment 9 2023-11-21 05:13:42 PST
(In reply to Ivan Enderlin from comment #8) > Someone else has tried this test program on macOS Sonoma, but on x86_64, and > it works, just like for Ross. It seems to be an issue on aarch64 only. Maybe. Looks like it. I've had a chance to try on an M1 machine now, and I repro the behavior you describe (though unfortunately I won't have time to dig deeper right away).
Mark Lam
Comment 10 2023-11-21 07:58:47 PST
Ivan, your test case implies that you're using the JSC API, which I don't think officially supported WebAssembly. WebAssembly is still available in WebViews. You say this is a breaking change and a blocker. What app is this breaking, and why does it need WebAssembly? Thanks.
Ivan Enderlin
Comment 11 2023-11-21 08:06:30 PST
Mark, I'm using JSC to execute Wasm on iOS, where I can't use another Wasm runtime (like wasmtime for instance). Our Rust SDK needs to work on multiple platforms. `WebAssembly` is defined in the global object, except now on aarch64, but I believe it's a bug/regression. It was previously working, it's no longer the case only on aarch64, that's a good sign of a regression :-). I've not tested on iOS though, but we need it to work on macOS too for development purposes. Using a WebView isn't an option here, it would imply to rewrite an entire component of our infrastructure just because of this regression.
Mark Lam
Comment 12 2023-11-21 08:26:06 PST
(In reply to Ivan Enderlin from comment #11) > Mark, I'm using JSC to execute Wasm on iOS, where I can't use another Wasm > runtime (like wasmtime for instance). Our Rust SDK needs to work on multiple > platforms. > > `WebAssembly` is defined in the global object, except now on aarch64, but I > believe it's a bug/regression. It was previously working, it's no longer the > case only on aarch64, that's a good sign of a regression :-). I've not > tested on iOS though, but we need it to work on macOS too for development > purposes. > > Using a WebView isn't an option here, it would imply to rewrite an entire > component of our infrastructure just because of this regression. Currently, JSC's Wasm implementation still requires JIT support in order to work. On iOS, JSC API clients never had JIT support. So, it's never been possible to run Wasm on iOS via a JSC API client. If you were using a WKWebView / SFSafariViewController, then Wasm is available. If `WebAssembly` is defined in the global object via the JSC API on iOS, then that's a bug that the symbol was ever exposed. Even so, Wasm would not have run. On macOS for aarch64, if your app is opted into the hardened runtime option (which adds greater security), then there is also no JIT support via the JSC APIs. This has been the case since before macOS Sonoma. Hence, it is not a regression. However, if your app did not opt into the hardened runtime, then it will be able to use the JIT, and Wasm will work.
Ivan Enderlin
Comment 13 2023-11-21 08:38:12 PST
Mark, do you mean that the fact it was working before _was a bug_, and now it _is fixed_? Well, since it works on x86_64, it means that the bug “is fixed” only on aarch64, but not yet on x86_64? What I don't understand is: where/how LLInt fits here? If JIT is disabled, isn't it possible to run Wasm only with the interpreter? That's what I thought was happening to be honest.
Ivan Enderlin
Comment 14 2023-11-21 09:11:23 PST
With this patch https://github.com/WebKit/WebKit/commit/2c0494fcc3fe018670c408476931c3698d9b2ee2, it is possible to use WebAssembly if JIT is off/disabled. Why JSC C API cannot have this configuration by default? Again, since this bug (described here) only happens on aarch64, is WebAssembly turns on and JIT off for x86_84?
Mark Lam
Comment 15 2023-11-21 09:57:33 PST
(In reply to Ivan Enderlin from comment #13) > Mark, do you mean that the fact it was working before _was a bug_, and now > it _is fixed_? Well, since it works on x86_64, it means that the bug “is > fixed” only on aarch64, but not yet on x86_64? You were mistaken about it ever working on iOS. On macOS, I think x86_64 does not support the hardened runtime option in your Xcode project. On aarch64, the hardened runtime option is supported. If you enable the hardened runtime option, then JIT will not be supported and you won’t be able to use Wasm. If you disable it, you can use it if you disable the hardened runtime option for your app’s Xcode project. > What I don't understand is: where/how LLInt fits here? If JIT is disabled, > isn't it possible to run Wasm only with the interpreter? That's what I > thought was happening to be honest. The current Wasm implementation still use JIT glue for marshaling arguments. Even the LLInt replies in this. (In reply to Ivan Enderlin from comment #14) > With this patch > https://github.com/WebKit/WebKit/commit/ > 2c0494fcc3fe018670c408476931c3698d9b2ee2, it is possible to use WebAssembly > if JIT is off/disabled. Why JSC C API cannot have this configuration by > default? That is Sony’s prep work for paving the way to Wasm LLInt working without JIT. AFAIK, LLInt still relies on JIT glue code today. > Again, since this bug (described here) only happens on aarch64, is > WebAssembly turns on and JIT off for x86_84? Again, this is not a bug and there is no regression. The feature you’re asking for has never existed on iOS. On macOS, you can use Wasm if you opt out of the hardened runtime option in your Xcode project.
Ivan Enderlin
Comment 16 2023-11-22 00:11:45 PST
Mark, I can't use a `WKWebView` because I need my Wasm module import functions to be defined as JS callbacks, so that I can implement them in Rust. As far as I know, it's not possible to pass `Function` objects from the “host” to a `WKWebView` via `postMessage`. Is there a safe way to achieve that maybe? > You were mistaken about it ever working on iOS. I'm sorry but… before running into this project, we have tested running Wasm on iOS and it was working great via JSC. 2 persons have tested it on 2 different devices, and we have seen the same thing: Wasm was running on iOS via JSC. Anyway, is there a chance that we will be able to run Wasm in a short-future without JIT, only purely with LLInt? Or is there a chance that JIT will be enabled inside JSC C API? Do you have a public roadmap about that topic? Thanks.
Justin Michaud
Comment 17 2023-11-22 17:34:12 PST
>I can't use a `WKWebView` because I need my Wasm module import functions to be defined as JS callbacks If you try https://developer.apple.com/documentation/webkit/wkscriptmessagehandler with worker + SAB + Async.await, you can probably get a nice speed improvement. In particular, I have been meaning to hack up a demo of how to do this for a while. It is a recipe for a much more responsive user experience, but I understand it is a lot of glue code. > I'm sorry but… before running into this project, we have tested running Wasm on iOS and it was working great via JSC Do you have a test case that reproduces this? The current test case does not actually execute any wasm. As Mark said, this should have crashed the second you tried to actually use WASM, unless you were using a WKWebView. Simulator acts mostly like macOS, so it is super important to test on real hardware. > Anyway, is there a chance that we will be able to run Wasm in a short-future without JIT, only purely with LLInt? Or is there a chance that JIT will be enabled inside JSC C API? Do you have a public roadmap about that topic? We have nothing public at this time > where I can't use another Wasm runtime You totally can, you just can't use JIT. For example, this claims to support iOS: https://github.com/wasm3/wasm3 (I have never used this, this is not an endorsement). We certainly do hope you try to use a WKWebView + callbacks though. Above all, the key takeaway is this: ***Opt out of hardened runtime on macOS to continue JITTIng. If that doesn't fix your problem, then this is a bug on our end that we need to fix. *** If wasm was ever running on iOS outside of a WKWebView, that certainly surprises everyone on our end. Cheers!
Ivan Enderlin
Comment 18 2023-11-23 02:48:46 PST
> Simulator acts mostly like macOS, so it is super important to test on real hardware. It was using a simulator, which likely explains why it was working. > You totally can, you just can't use JIT. For example, this claims to support iOS: https://github.com/wasm3/wasm3 (I have never used this, this is not an endorsement). Yeah, I was trying to use `wasm3` or any other interpreters out there. You should consider allowing Wasm to run with JavaScriptCore. That could be awesome :-).
Mark Lam
Comment 19 2023-11-23 13:48:46 PST
Resolving as WONTFIX because the code is behaving as intended.
Note You need to log in before you can comment on or make changes to this bug.