fermyon / spin

Spin is the open source developer tool for building and running serverless applications powered by WebAssembly.
https://developer.fermyon.com/spin
Apache License 2.0
5.26k stars 249 forks source link

how to add new language support? #2067

Open bobzhang opened 1 year ago

bobzhang commented 1 year ago

It would be nice to have a minimal example using wat so that we are clear how to add new language support. wasi does not provide network service support, it is unclear to me how spin get the network support? thanks

Background: I am working on a new language called MoonBit(moonbitlang.com) optimized for Wasm, would be interesting to make it available for Spin users

itowlson commented 1 year ago

Spin talks to guests (Wasm applications) using the WebAssembly component model. You can find the interface declarations at https://github.com/fermyon/spin/tree/main/wit - in particular we track the wasi-http specification for HTTP applications.

For example, for a component to run on a Spin HTTP trigger, all it needs to do is implement the wasi-http/incoming-handler interface defined in https://github.com/fermyon/spin/blob/main/wit/deps/http/incoming-handler.wit. All the SDKs do is implement that in ways that are more idiomatic to the language.

The challenge for a new language such as MoonBit is implementing the binary interface. The Bytecode Alliance wit-bindgen tool (https://github.com/bytecodealliance/wit-bindgen) handles this for a range of existing languages, but as the author of a new language you'll be a bit on your own. I am not sure whether WAT samples exist for this sort of thing - you can find a minimal example of a component written in WAT at https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#component-definitions - @alexcrichton may have a better sense of what sort of toolchain you would need to go from a new language to component-model WAT to binary Wasm.

(Also, depending on whether MoonBit chooses to target the component model or Wasm core modules, you may find it more practical to use older WITs - you can find those in the WIT folder on older Spin tags, and we still support core modules using those WITs for backward compatibility. But then you will need to find matching documentation for the binary interface and bindings generation, which is a whole other challenge.)

Hope this helps - Wasm is an exciting opportunity for language authors for sure!

alexcrichton commented 1 year ago

Currently as far as I know all existing languages and toolchains will emit a core wasm module as their first artifact and then afterwards to produce a component the wit-component Rust crate is used (also the wasm-tools component new CLI). That's likely the route you'll want to take for MoonBit as well and you can see how the other languages, such as C and Rust, do it in the wit-bindgen repository.

melissaklein24 commented 6 months ago

@bobzhang Did you get your question answered? If so, we can close the issue.

magick93 commented 4 months ago

Would be great to see support for https://moonbitlang.com/

itowlson commented 4 months ago

@magick93 That wiork should be able to happen on the MoonBit side. If MoonBit can call WASI imports (0.1 or 0.2) and export functions/interfaces using WASI (0.1 or 0.2) then it should be possible for a MoonBit component to export a HTTP entry point and invoke Spin APIs (as well as "built in" functions like print provided the MoonBit runtime maps those to WASI). However, from a quick skim of the MoonBit docs, it currently seems more aimed at a JavaScript environment. There is mention of a Wasm-GC backend but I'm not sure how that relates to WASI. (Also, if it requires GC over and above plain WASI, that might be a blocker at the moment. I am not sure the Spin Wasm engine supports GC yet, although I am sure we will get it at some point!)