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

feat(interface-types) Implement Interface Types (WIT) #787

Merged
merged 81 commits into from
Feb 13, 2020

Conversation

Hywan
Copy link
Contributor

@Hywan Hywan commented Sep 13, 2019

So far, this PR implements a new crate named wasmer-interface-types. The goal is to implement the WebAssembly Interface Types (WIT) proposal, https://github.com/WebAssembly/interface-types. Keep in mind the proposal is highly unstable and experimental.

The wasmer-interface-types is designed to be runtime agnostic, which means that there is no connection between this crate and wasmer-runtime-core or wasmer-runtime (or any backend crates). The hope is that other runtimes could use wasmer-interface-types according to their needs.

The wasmer-interface-types is composed of 4 parts:

  • AST: The WIT language, represented as an AST (it's not really abstract though),
  • Decoders: So far, it contains only one parser that reads the WIT binary language and produces an AST,
  • Encoders: So far, it contains only one compiler that transforms the AST into "WIT.wat”, i.e. the textual representation of an Interface Types AST
  • Instructions: WIT defines a new concept called Adapters. An adapter contains a set of instructions. Those instructions are executed when data are bound. So, in more details, this module contains:
    • interpreter.rs, a stack-based interpreter, defined by:
      • A compiler that transforms a set of instructions into a set of executable instructions,
      • A stack,
      • A runtime that holds the “invocation inputs” (arguments of the interpreter), the stack, and the Wasm instance (which holds the exports, the imports, the memories, the tables etc.),
    • stack.rs, a very light and generic stack implementation, exposing only the API required by the interpreter,
    • wasm/*.rs, a set of enums, types, and traits to represent a Wasm runtime —basically this is the part a runtime should take a look to support the wasmer-interface-types crate—.

Progression:

  • WIT binary parser,
  • WIT.wat compiler,
  • Interpreter:
    • Wasm runtime traits to represent:
      • Instance,
      • Export,
      • Memory,
      • Import,
      • Table,
    • Generic stack implementation,
    • Implemented instructions:
      • arg.get,
      • call,
      • call-export,
      • read-utf8,
      • write-utf8,
      • as-wasm,
      • as-interface
      • table-ref-add
      • table-ref-get
      • call-method
      • make-record
      • get-field
      • const
      • fold-seq
      • add
      • mem-to-seq
      • load
      • seq.new
      • list.push
      • repeat-until
      • seq-to-mem
      • store
  • Plug wasmer-interface-types into wasmer-runtime-core

@Hywan Hywan added the 📦 lib-deprecated About the deprecated crates label Sep 13, 2019
@Hywan Hywan self-assigned this Sep 13, 2019
@Hywan Hywan force-pushed the feat-interface-types branch from a4972cc to 6ec35c8 Compare September 18, 2019 15:15
@Hywan Hywan added 🎉 enhancement New feature! 📚 documentation Do you like to read? 🧪 tests I love tests labels Sep 20, 2019
Copy link
Contributor

@MarkMcCaskey MarkMcCaskey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good to me! A lot of my feedback is stylistic but there are a few correctness and other larger concerns here too. Once those get fixed up, I think it should be good to go!

lib/interface-types/src/ast.rs Outdated Show resolved Hide resolved
input_types: Vec<InterfaceType>,

/// The function output types.
output_types: Vec<InterfaceType>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth considering using the structs with the same fields inside this enum if you haven't already. It may not make sense given how it's used -- I haven't read most of the code yet; I think this level of duplication can make sense though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by:

It's worth considering using the structs with the same fields inside this enum if you haven't already.

?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the enum's fields are identical to the structs with the same/similar names. It'd be possible to remove most of the fields in the enum and replace it with 1 instance of the correct struct. It's a minor thing and I think there are convincing arguments for both doing it and not doing it.

},
}

/// Represented a forwarded export.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the docs should explain what forwarding is

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not super defined in the spec yet :-D. It should be used to “rename” an export, like main to _start. I'm not sure it will be kept in the future.

lib/interface-types/src/decoders/binary.rs Show resolved Hide resolved
lib/interface-types/src/decoders/binary.rs Show resolved Hide resolved
lib/interface-types/src/encoders/wat.rs Outdated Show resolved Hide resolved
lib/runtime-core/Cargo.toml Outdated Show resolved Hide resolved
lib/interface-types/src/interpreter/instructions/call.rs Outdated Show resolved Hide resolved
lib/interface-types/src/lib.rs Show resolved Hide resolved
Hywan added 13 commits February 13, 2020 11:24
As @MarkMcCaskey noted, `Type` can be corrupted because `field_names`
and `field_types` must have the same length. This patch removes the
public visibility, and adds methods like `new`, `add_field`,
`field_names` and `field_types` to encapsulate `Type` internal data.
The LEB parser is renamed `uleb`. It now checks for overflow, and
badly-formed bits, resp. `TooLarge` or `Eof`. More test cases are
added, whose from the DWARF 4 standard.
Instead of using `str::from_utf8_unchecked`, this patch updates the
code to use `str::from_utf8` and handles the error appropriately.
@Hywan
Copy link
Contributor Author

Hywan commented Feb 13, 2020

bors r+

bors bot added a commit that referenced this pull request Feb 13, 2020
787: feat(interface-types) Implement Interface Types (WIT) r=Hywan a=Hywan

So far, this PR implements a new crate named `wasmer-interface-types`. The goal is to implement the WebAssembly Interface Types (WIT) proposal, https://github.com/WebAssembly/interface-types. Keep in mind the proposal is highly unstable and experimental.

The `wasmer-interface-types` is designed to be _runtime agnostic_, which means that there is no connection between this crate and `wasmer-runtime-core` or `wasmer-runtime` (or any backend crates). The hope is that other runtimes could use `wasmer-interface-types` according to their needs.

The `wasmer-interface-types` is composed of 4 parts:
* AST: [The WIT language, represented as an AST](https://github.com/Hywan/wasmer/blob/feat-interface-types/lib/interface-types/src/ast.rs) (it's not really abstract though),
* Decoders: So far, it contains only [one parser that reads the WIT binary language](https://github.com/Hywan/wasmer/blob/feat-interface-types/lib/interface-types/src/decoders/binary.rs) and produces an AST,
* Encoders: So far, it contains only [one compiler that transforms the AST into "WIT.wat”](https://github.com/Hywan/wasmer/blob/feat-interface-types/lib/interface-types/src/encoders/wat.rs), i.e. the textual representation of an Interface Types AST
* Instructions: WIT defines a new concept called Adapters. An adapter contains a set of instructions. Those instructions are executed when data are bound. So, in more details, this module contains:
  * [`interpreter.rs`](https://github.com/Hywan/wasmer/blob/feat-interface-types/lib/interface-types/src/interpreter/mod.rs), a stack-based interpreter, defined by:
    * A compiler that transforms a set of instructions into a set of _executable_ instructions,
    * A stack,
    * A runtime that holds the “invocation inputs” (arguments of the interpreter), the stack, and the Wasm instance (which holds the exports, the imports, the memories, the tables etc.),
  * [`stack.rs`](https://github.com/Hywan/wasmer/blob/feat-interface-types/lib/interface-types/src/interpreter/stack.rs), a very light and generic stack implementation, exposing only the API required by the interpreter,
  * [`wasm/*.rs`](https://github.com/Hywan/wasmer/blob/feat-interface-types/lib/interface-types/src/interpreter/wasm/structures.rs), a set of enums, types, and traits to represent a Wasm runtime —basically this is the part a runtime should take a look to support the `wasmer-interface-types` crate—.

Progression:

* [x] WIT binary parser,
* [x] WIT.wat compiler,
* [ ] Interpreter:
  * [ ] Wasm runtime traits to represent:
    * [x] Instance,
    * [x] Export,
    * [x] Memory,
    * [x] Import,
    * [ ] Table,
  * [x] Generic stack implementation,
  * [ ] Implemented instructions:
    * [x] `arg.get`,
    * [x] `call`,
    * [x] `call-export`,
    * [x] `read-utf8`,
    * [x] `write-utf8`,
    * [ ] `as-wasm`,
    * [ ] `as-interface`
    * [ ] `table-ref-add`
    * [ ] `table-ref-get`
    * [ ] `call-method`
    * [ ] `make-record`
    * [ ] `get-field`
    * [ ] `const`
    * [ ] `fold-seq`
    * [ ] `add`
    * [ ] `mem-to-seq`
    * [ ] `load`
    * [ ] `seq.new`
    * [ ] `list.push`
    * [ ] `repeat-until`
    * [ ] `seq-to-mem`
    * [ ] `store`
* [ ] Plug `wasmer-interface-types` into `wasmer-runtime-core`

Co-authored-by: Ivan Enderlin <[email protected]>
@bors
Copy link
Contributor

bors bot commented Feb 13, 2020

Build succeeded

@bors bors bot merged commit c697e68 into wasmerio:master Feb 13, 2020
Hywan added a commit to Hywan/wasmer that referenced this pull request Feb 13, 2020
bors bot added a commit that referenced this pull request Feb 13, 2020
1214: test(interface-types) Add `wasmer-interface-types` to `make check` r=MarkMcCaskey a=Hywan

Sequel of #787. Forgot to update the changelog, and to add `wasmer-interface-types` to `make check`.

Co-authored-by: Ivan Enderlin <[email protected]>
Co-authored-by: Mark McCaskey <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📚 documentation Do you like to read? 🎉 enhancement New feature! 🧪 tests I love tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants