bytecodealliance / wit-bindgen

A language binding generator for WebAssembly interface types
Apache License 2.0
1.04k stars 195 forks source link

Support generating and using a human-readable form of the component type #994

Closed dicej closed 4 months ago

dicej commented 4 months ago

Per, https://github.com/dotnet/runtimelab/pull/2614#discussion_r1661386986, I've been adding WASIp2 support to .NET, and the current approach involves checking the wit-bindgen-generated bindings into source control (along with a script to regenerate them as desired), analogous to what we've done in wasi-libc.

However, the maintainers are concerned about the component type .o file being opaque and difficult to audit from a security perspective. I'd like to propose another option for making that information available to wasm-component-ld: e.g. emitting a WAT file that could be passed directly to wasm-component-ld via a linker flag such as -Wl,--component-type=foo.wat.

Note that while .NET/C# is the primary use case here, it could also be useful for avoiding binary blobs elsewhere, e.g. wasi-libc.

alexcrichton commented 4 months ago

My recommendation for this might be to use *.wit instead of *.wat, but otherwise I think this is reasonable to support. The *.wat format is subject to change over time and given that *.wit is more often human read/written it's more likely to have long-term stability around it. I'm not sure what the exact flag to wasm-component-ld would be but being able to pass a WIT world somehow as "here's some more bindings" seems reasonable to me.

dicej commented 4 months ago

@alexcrichton If we use WIT, will that mean we need to point wasm-component-ld to a directory of WIT files in the general case? Or do we have a way to pack an entire world (including its dependencies) into a single WIT file?

alexcrichton commented 4 months ago

With the freshly-added ability to have multiple packages in a single *.wit file it should be possible nowadays to do a single-file-representation. It'd still require a second/auxiliary argument to specify both a *.wit file and a world within it, though.

pavelsavara commented 4 months ago

We are blocked on this, so I'm exploring alternatives, which would allow us to make progress already.

Is there a way how to express the same via C code ? (wasip2 target, WASI SDK 22)

Could something like this work ?

__attribute__((import_module("wasi:http/types@0.2.0"),import_name("[constructor]outgoing-request")))
extern int32_t WasiHttpWorld_wit_imports_wasi_http_v0_2_0_23_wasi_3A_http_2F_types_40_0_2_0_23__5B_constructor_5D_outgoing_request (int32_t);

Or that's just core module import rather than component import ? Do I need to care about transitive dependency ? If so, how do I express it ?

Alternatively, is there already existing tool which could roundtrip this .o file to some human readable form and back ?

dicej commented 4 months ago

@pavelsavara I'm in the process of addressing this, and should have a solution today or early next week (and certainly by the time you're back from your time off). I expect any alternative approaches would take just as long to implement, so I'd say let's stick to the current plan unless you see an issue with it (i.e. modify wit-bindgen to produce a .wit file, and modify wasm-component-ld to accept that .wit file).

dicej commented 4 months ago

This has been addressed as of https://github.com/bytecodealliance/wit-bindgen/pull/1002 and https://github.com/bytecodealliance/wasm-component-ld/pull/32.