The new way to build wasm in Rust

I'm trying to understand some of the mechanics behind @steveklabnik's wasm demo: Demo: Minimal add function with no_std - Hello, Rust!

#![feature(lang_items)]
#![no_std]

#[no_mangle]
pub fn add_one(x: i32) -> i32 {
    x + 1
}

What the meaning of the first two lines? I'm assuming no_std means do not include the standard library? Is this to lower the file size of the library?

Good for you to ask, because that's not necessary anymore.
I'll explain anyway:

#![no_std]

As you mentioned it removes the standard library. All you have left is core.
This usually reduces size significantly, but also reduces the feature set.

#![feature(lang_items)]

Some operations in Rust are handled by library-implemented functionality, yet they are core to the language. This feature allows to supply your own implementation of the operations, see also the unstable book.

In combination these two things allow to build a super-minimal nothing-but-bare-types library. For the very first wasm support this was necessary to make it minimal.

However, libstd totally works on wasm as well[*1] and after some bugfixes the compiler is able to spit out a mostly-unused-stuff removed library. And with libstd you already get the lang_items implemented.
Now the compiler is currently not smart enough to actually remove dead code from the compiled wasm module, that's why wasm-gc exists to reduce the module size further. Once we get an actual linker (such as LLVM's own lld) this will not be necessary anymore.
The module presented on https://www.hellorust.com/demos/add/index.html uses stdlib and the mentioned wasm-gc and spits out a 108-byte module (which btw is the same you'd get with the above no_std+lang_items example). That's as close to minimal as it gets right now.

[*1]: Large parts will just panic, because they are effectively unimplemented for the wasm target

5 Likes

Thanks for the explanation Jan-Erik!

I made a mistake of assuming the code snippet on the hellorust site was the same as Steve's original gist, it isn't (should read the text more closely :wink: )