Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wit/bindgen: implement post-return functions #118

Open
3 tasks
ydnar opened this issue Jun 24, 2024 · 2 comments
Open
3 tasks

wit/bindgen: implement post-return functions #118

ydnar opened this issue Jun 24, 2024 · 2 comments
Assignees
Labels
bug Something isn't working

Comments

@ydnar
Copy link
Collaborator

ydnar commented Jun 24, 2024

For exported (go:wasmexport) functions, the Canonical ABI specifies an optional post-return function, which is exposed to the WebAssembly host as:

cabi_post_ + original function name

The purpose of the post-return function is to allow the component to free any memory allocated in the returned value.

Given that Go (and TinyGo) uses a garbage collector to free unreferenced memory, the GC should eventually free these allocations. However, pointers may be passed to the host (out of the component), leaving no references to the memory in the Go stack or heap. This could lead to memory being prematurely freed, causing a crash.

Given the constraints that this code will be executed under( WASI 0.2 and components currently operated in a single-threaded, non-reentrant manner, where memory is copied immediately from guest to host), I believe it is unlikely that the Go GC will have an opportunity to free the memory before the host copies it.

However, as we look to implement WASI 0.2 and Component Model on mainline Go, we should probably implement a mechanism to ensure pointers are referenced when passed in and out of the WebAssembly boundary to ensure they are not garbage collected before use.

Implementation

The implementation of post-return functions (cabi_post_*) was wrong. #119 implemented two changes:

  1. Correct the function signature of post-return functions, deriving from the flattened (Core WebAssembly) version of exported functions, rather than the original function signature.
  2. Disable generation of Go *PostReturn functions, including user-defined side, until a point at which we can generate a correct implementation.

The implementation of post-return functions for Go needs more design work. Given that Go has a GC, the returned pointers should eventually be garbage collected. Areas of exploration:

  • Create a bookkeeping mechanism to keep track of pointers passed to wasmexport functions and free/release them when passed back via a post-return function.
  • Determine whether this should also apply to any allocations created with cabi_realloc.
  • For Go (as opposed to TinyGo), figure out a way to handle pointers in variant types, which need to represent both non-pointer and pointer values in the same memory location. This might involve sidecar returns from variant-returning or accepting functions.
@ydnar ydnar added the bug Something isn't working label Jun 24, 2024
@ydnar ydnar self-assigned this Jun 24, 2024
@ydnar ydnar changed the title wit/bindgen: implement correct post-return function signature wit/bindgen: implement post-return functions Jun 28, 2024
@sammyne
Copy link

sammyne commented Jul 16, 2024

Does projects based on bytecodealliance/wit-bindgen with tinygo has this problem?

@ydnar
Copy link
Collaborator Author

ydnar commented Jul 16, 2024

wit-bindgen uses Cgo, so it shares the same behavior as the C generator with respect to post-return functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants