design
design copied to clipboard
Proposal: Non-Web Embedder APIs
I would like to discuss about non-Web embedder API.
Introduction
WebAssembly aims at being run everywhere. It first came inside Web browsers, and naturally, with a Web specification. It is part of the W3C for instance.
Time flies! Now we have multiple non-Web runtimes/VM, such as Wasmer [1] or wasmtime [2]. Those runtimes have been integrated in multiple languages, or standalone runtimes have been written for specific languages. Today, we can execute WebAssembly in PHP [3], Python [4, 5], Ruby [6], Go [7, 8, 9] and so on. This is not an exhaustive list.
With the rise of ⛄️-bindings, there is an important need to define standards API to interact with a runtime/VM. Let's use the state of WebAssembly runtimes/VM in Go as an example to illustrate:
- With
wasmerio/go-ext-wasm
[7]:
instance, _ := wasmer.NewInstance(wasmBytes)
result, _ := instance.Exports["sum"](1, 2)
- With
go-interpreter/wagon
[8]:
module, _ := wagon_wasm.ReadModule(bytes.NewReader(wasmBytes), func(name string) (*wagon_wasm.Module, error) { … })
vm, _ := wagon_exec.NewVM(module)
result, _ := vm.ExecCode("sum", int64(1), int64(2))
- With
perlin-network/life
[9]:
vm, _ := life.NewVirtualMachine(wasmBytes, life.VMConfig{}, &life.NopResolver{}, nil)
entryID, _ := vm.GetFunctionExport("sum")
result, _ := vm.Run(entryID, int64(1), int64(2))
API are really different, and the examples are only about instantiating a module, and calling an exported function. The other API are so much more different, like getting the memory, reading from or writing into it, manipulating tables, globals etc.
For ⛄️-bindings, we need to get standards, so that different tools can generate bindings that are VM/runtime agnostic. For instance, to implement the utf8-str
or copy
bindings, a view of the memory might be necessary, with a specific API to read it. That would be much more confortable to generate bindings without having to deal with VM specificities.
Approach
I'm not sure WebAssembly working groups are responsible to write such standards. Do you confirm that? Do we expect such standards to rise from the language communities?
For the JS embedder, the W3C is in charge to write the specification. Many people are involved in both universes: WebAssembly, and W3C, and that's totally fine. I assume the situation will be very similar with non-Web embedders.
PHP. The PHP group writes RFC [10] but focused on the language itself, not extensions. However, there is the PHP-FIG [11] (for Framework Interoperability Group) that writes PSR (for PHP Standards Recommendations). It is focused on framework API, but it may be possible that WebAssembly fits here. If not, it is possible to publish a PSR-ish package which only contains interfaces.
Python. Similar to PHP RFC, Python has PEP [12] (for Python Enhancement Proposals). It is also focused on the language itself, not extensions. I'm not aware of another standard group. In case none exists, it could be a solution to publish a package that contains mixins/abstract classes that define the interface. But who will be author or the owner of the package? It should be the WebAssembly working groups to avoid any potential dominance issues in the future.
Ruby. I'm not familar with Ruby that much. I know Ruby supports interfaces, so a similar methology to PHP or Python can be applied.
Go. Same than PHP, Python, or Ruby, a package can be published that contains interfaces.
The goal of the discussion here is to define who is responsible to write such standards. Is it us (WebAssembly working groups)? Is it the language communities? Do we need to “pilot”/guide/lead this effort? If the language communities write the standard, who's the owner? Do we have “something to say” at some point, like a veto or something? Those are deliberately opened questions.
This is the intention of the wasm-c-api proposal, to provide a C and C++ API for standardizing access to a wasm engine. I think you're right that we'll want to do the same for other languages too. It seems reasonable to me that we would standardize them here, just like we have with the JS API, and plan to with the C API.
OK. So, I don't know what's the best way to start this work. I'm very likely to start drafting repositories using wasm-c-api
as a base template, and finally link them here. Is that OK?
I think that's a good way to start. These should be treated as proposals, so should follow the normal proposal process. We'll need to decide how to interpret some of the steps that don't quite fit, however.
I started two repositories, resp. for Python and PHP, before holidays, and then forgot to link them here. Time to fix that!
- https://github.com/wasmerio/wasm-python-api
- https://github.com/wasmerio/wasm-php-api
Those are drafts! Feedbacks are welcomed.
Just got back from leave. Any progress on these?
I missed the notification, sorry Ben! I can improve/iterate over what's done. I should probable focus on one language at a time to avoid repeating potentially the same errors.
I'll try to update the Python API as soon as possible. cc @jubianchi