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

WASI reactors #6757

Closed
DagAgren opened this issue Oct 21, 2020 · 6 comments · Fixed by #9178
Closed

WASI reactors #6757

DagAgren opened this issue Oct 21, 2020 · 6 comments · Fixed by #9178
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. os-wasi
Milestone

Comments

@DagAgren
Copy link

I can't seem to find any information about this, so sorry if I am just missing something, but, does zig support building WASI "reactors"?

The concept of a reactor in WASI is a module that does not have a regular start function that runs and exits, but instead has a simpler _initialize() entry point, that just does whatever low-level initialisation the binary and WASI implementation needs (calling global constructors, setting up the preloaded directories), and then exits, leaving everything in place. The hosting environment then calls whatever function the module exports to actually do work.

Is this currently possible in zig, and if not, would it be possible to add support for it?

@Vexu Vexu added arch-wasm 32-bit and 64-bit WebAssembly enhancement Solving this issue will likely involve adding new logic or components to the codebase. labels Oct 21, 2020
@Vexu Vexu added this to the 0.8.0 milestone Oct 21, 2020
@zigazeljko
Copy link
Contributor

You can manually export the _initialize function and use build-lib (instead of build-exe):

const std = @import("std");

export fn _initialize() void {
    std.debug.print("hello, world!\n", .{});
}

Other than that, there is no special support for this.

@daurnimator daurnimator added os-wasi and removed arch-wasm 32-bit and 64-bit WebAssembly labels Oct 21, 2020
@DagAgren
Copy link
Author

The issue, I guess, is that wasi-libc relies on initialisation that happens in either _start() or _initialize(), and things like fopen() will refuse to work without it. But I am not sure if there is an exposed way to trigger this initialisation outside of the default crt1.o and crt1-reactor.o.

@DagAgren
Copy link
Author

DagAgren commented Oct 22, 2020

Also, it seems this happens through __attribute((constructor))__ in wasi-libc. How is that handled in zig? Is it supported?

@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 Nov 6, 2020
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 May 19, 2021
@mathetake
Copy link
Contributor

mathetake commented Jun 2, 2021

So the current nightly Zig does not output .wasm directly in zig-out, but put it in an archive with .o extension and a "mangled" file name for "build-lib".

$ cat test.zig
const std = @import("std");

export fn _initialize() void {
    std.debug.print("hello, world!\n", .{});
}

$ zig build-lib test.zig -target wasm32-wasi

$ ar -t libtest.a
zig-cache/o/aeb516dcd17dbf8e134607b3a84ef354/test.o

$ wasm-objdump zig-cache/o/aeb516dcd17dbf8e134607b3a84ef354/test.o --headers

test.o:	file format wasm 0x1

So I did a workaround in my Proxy-Wasm Zig SDK (https://github.com/mathetake/proxy-wasm-zig-sdk/pull/8) and setup the build.zig to produce "shared" library in order to get raw Wasm files with ".wasm" extension and unmangled file names for reactors.

Not only the above drift issue, I am also currently having kind of workaround for lib constructor in my reactor setup in my Proxy-Wasm ZIg SDK something like:

extern fn __wasm_call_ctors() void;

export fn _initialize() void {
    __wasm_call_ctors();
    // Do application specific setup
}

Having said that, I think I want to have a standardized way of producing WASI reactors.

In rust, they have a dedicated option for producing reactors (rust-lang/rust#79997), so maybe this is something we want to follow in Zig as well. My proposal here is that

  • Having a option for producing WASI reactors for "build-exe", not for "build-lib"(s),
    • Users do not need to define _initialize symbol by them selves, just define public main function as usual.
  • If that option enabled, we only have reactor specific entrypoint (_initialize) and not define/export _init symbol in the final Wasm binary.
  • In _initialize, invoke WASI constructors (as I did in TinyGo's WASI command target), and then the main function by users.

@kubkon I saw you mentioned WASI reactors in the PR (#8837), any thoughts ^? If we reach the consensus here, I would be more than happy to contribute. Thanks!

@kubkon
Copy link
Member

kubkon commented Jun 2, 2021

#8837 unified the behavior of build commands for Wasm, where build-lib will by default produce a static archive that can be used for further linking with wasm-ld. If you want to generate a module using build-lib you should pass additional -dynamic flag to the invocation.

As far as a WASI reactor is concerned, I haven't put much thought into that yet, however, given that we now ship WASI libc, it would be good to first work out how to expose this functionality in C (i.e., with zig cc) since #8837 left it a TODO. For pure Zig, we have to be careful since Zig doesn't invoke any ctors. In fact, it is currently assumed the user's responsibility to call any relevant startup code that would otherwise involve dynamic memory allocation such as fetching the preopens, hence the actual startup amounts to calling _main in start.zig:

if (native_os == .wasi) {
.

@mathetake
Copy link
Contributor

@kubkon thanks for the response! I created a draft PR for supporting WASI reactor in zig cc: #8978 by leveraging the existing -mexec-model flag (https://reviews.llvm.org/D62922). Do you think this is the right way to do?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. os-wasi
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants