tinygo-org / tinygo

Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
https://tinygo.org
Other
15.18k stars 889 forks source link

Implement recover for wasm architecture #2914

Open Vilsol opened 2 years ago

Vilsol commented 2 years ago

recover was implemented for most architectures in #2331, however wasm was left out.

As suggested here https://github.com/tinygo-org/tinygo/blob/4c647847247316bae553f9b9a8c7da4034edd199/compiler/defer.go#L29-L33 it should probably utilize the proposed exception handling: https://github.com/WebAssembly/exception-handling

Opened as per expected closure of #891

codefromthecrypt commented 1 year ago

Few points which could lead to a better description and possibly another way out.

Summarizing the technical concern

There are a mix of opinions and technical concerns in the 60+ comments in the PR preceding this. It would be nice to have a summary here about what is a technical constraint vs a cultural disinterest in defer.

blocking on incomplete WebAssembly proposals

While some land faster than others, blocking on WebAssembly proposals can prevent implementation for periods of a year or more. The good news is that the proposal mentioned here is at least in phase 3, so it is more likely a when vs if, though it is possible still to be canceled before "finished".

https://github.com/WebAssembly/proposals

How do others get by?

I tried the test data in normal go GOARCH=wasm GOOS=js and it works, all the defer cases. A quick point on why it works in Go and why it working there has no impact to the design here could help.

atdiar commented 1 year ago

To add a use-case, when compiling with the go compiler, it allows us to recover from panics by displaying a relevant message in the browser.

aykevl commented 1 year ago

I tried the test data in normal go GOARCH=wasm GOOS=js and it works, all the defer cases. A quick point on why it works in Go and why it working there has no impact to the design here could help.

You are correct, but note that the Go toolchain emits very different WebAssembly than TinyGo does. And as a result, TinyGo often makes much smaller binaries. I haven't really looked into how it works to be honest, but can't think of a way to implement recover without many changes to the compiler for a feature that is going to be relatively short-lived (the exception handling proposal is certainly the better way to implement recover).

We implemented goroutines using a big giant hack called Asyncify. We can maybe do the same for defer/recover, although the cost/benefit ratio seems far higher for recover.

While some land faster than others, blocking on WebAssembly proposals can prevent implementation for periods of a year or more. The good news is that the proposal mentioned here is at least in phase 3, so it is more likely a when vs if, though it is possible still to be canceled before "finished".

While frustrating, I think this is the most reasonable way forward. Correct me if I'm wrong, though. I'd love to have recover properly supported on all platforms. If you want to speed this up, please try to get exception handling implemented in wasmtime because that's an important VM that doesn't support it yet: https://github.com/bytecodealliance/wasmtime/issues/3427 There is also wasmer that also lacks support: https://github.com/wasmerio/wasmer/issues/3100

magic-akari commented 3 months ago

Hi there, I'm reaching out to kindly inquire if there have been any recent developments or updates regarding this matter.

Considering that we're now in 2024 and exception handling is nearly a standard feature in mainstream browsers, I'm curious to know if there have been any changes or advancements in TinyGo's implementation of recover for the WASM target.

Thank you for your attention to this, and I look forward to any information you can provide.

abourget commented 1 month ago

Got caught by a recover call too.. do you guys have an idea if/when this would be solved?

aykevl commented 1 month ago

I have implemented recover for WebAssembly. I'll need to clean up the code and then I can make a PR. But note:

EDIT: see https://github.com/tinygo-org/tinygo/pull/4380