WebAssembly / interface-types

Other
641 stars 57 forks source link

Add a draft "canonical ABI" #140

Closed alexcrichton closed 2 years ago

alexcrichton commented 2 years ago

This PR proposes a "canonical ABI" for interface types. This feature was alluded to in Luke's recent presentation to the CG, and this PR intends to flesh it out more and get a more formal specification of what it might be.

The idea of a canonical ABI is that the adapter language for interface types is one of the most complicated parts of the proposal, but with a canonical ABI we might be able to separate out the adapter language to a future proposal so we can get the goodness of interface types on a smaller time-scale.

The ABI proposed here is not intended to be a "one size fits all" ABI. It does not express the full power of interface types as-proposed today (intentionally). It's hoped, though, that the adapter language as proposed in this repository right now can be seen as largely just an optimization over what the canonical ABI specifies. This way languages and tooling can work with the canonical ABI by default, and if necessary for performance a custom ABI can be used with custom adapters in the future. One way to think about this canonical ABI is that it's a generalization of the current list.lift_canon into encompassing entire function signatures in addition to lists.

This PR describes the canonical ABI with a large amount of Python-like pseudo-code which describes the lift and lower operations for types, culminating in a fuse function which shows precisely how lifting/lowering happens when modules call each other.


As a note this is a reopening of https://github.com/WebAssembly/interface-types/pull/132 with a new base branch of main after the branch was renamed.

taralx commented 2 years ago

Looks great to me. :) There's an "f31" typo that seems to have snuck in.

taralx commented 2 years ago

One note: I find the "import" and "export" terminology confusing -- I've been mentally translating it into "parameter" or "result" as appropriate, but I sometimes get it backwards...

peterhuene commented 2 years ago

I did not mean to approve this PR (too many GitHub tabs open). Sorry about that!

sandstrom commented 2 years ago

@alexcrichton Awesome to see progress on this! ⭐

badeend commented 2 years ago

Buffers are intended to behave similarly to handle where they cannot be forged, but unlike handle they are only a temporary reference which lives for the duration of a function call (and can only show up as parameters to functions). This enables efficient binding of APIs like read and write where the canonical ABI is simply passing a pointer/length.

If I understand correctly, buffers require special notation because you want to statically verify that the buffer passed in as an argument can not be accessed anymore after the call has finished? For example:


// This is some wasm module:

let my_large_buffer = // ...

another_wasm_module::process(&my_large_buffer);

// Here

You want to make sure that there is no way for another_wasm_module to read or write to that my_large_buffer anymore at the time of executing // Here (or later). Correct?

If so, could this be solved using a more generic type which is defined to be unusable after the functions returns? I.e.

That way, Buffers can be just™ a WASI module.


Updated: Changed wording. Remembered that interface types are supposed to compile away and not introduce new Wasm types. Yet, the general idea still holds.

rektide commented 2 years ago

im curious what if any places this is being discussed or worked on? last commits here are from july.

the other piece of Component Model, module-linking, seems to be under fairly active development. does that work need to get closer to release before this PR can be revisited? https://github.com/WebAssembly/component-model

lukewagner commented 2 years ago

That's a great question. I've been working on a branch in the component-model repo that combines module-linking and MVP-interface-types (viz., using the canonical ABI instead of custom adapters) into a single simpler and easier-to-understand AST and binary format. While it's not there yet, the idea is to include an updated form of the CanonicalABI.md in that branch, better reflecting the current state of wit-bindgen. In the meantime, I'd discuss the canonical ABI in the wit-bindgen repo, where there is active prototyping.

lukewagner commented 2 years ago

Just as an update here, the PR I mentioned in the last comment is up. Still unfortunately no updated CanonicalABI.md but that's what I'm going to actively work on now that the merged PR is up.

lukewagner commented 2 years ago

Finally done in component-model/#23, so closing this issue.