Let's pretend that life-before-main exists for Rust targeting WebAssembly

Overview

Let's pretend that life-before-main exists for Rust targeting WebAssembly.

Installation

Add a dependency on wasm-init. This crate intentionally provides a no-op implementation for non-wasm platforms, so cfg handling isn't necessary and we don't pull in unused extra deps.

[dependencies]
wasm-init = "0.2"

User Code

Add as many calls to wasm_init! as required on the Rust side, e.g. for decentralised plugin registration or collecting data from all types that use a particular derive macro.

wasm_init::wasm_init! {
	// literally any code you want to run at startup goes here
}

Initialisation

To ensure your wasm_init! calls are executed on startup, you have three options. Note that all of these options are idempotent - multiple invocations are perfectly safe (if unnecessary), even in a threaded context.

Auto-init feature

If you'd like to skip manually initialising wasm-init, you can enable the auto-init feature as part of the dependency:

[dependencies]
wasm-init = { version = "0.2", features = [ "auto-init" ] }

But please bear in mind that this will prevent you from using a wasm bindgen start function elsewhere in your project.

From Rust

Call the wasm_init::wasm_init function inside your Rust entrypoint.

From JavaScript/TypeScript

Call the wasm_init export from your built module.

<script type="module">
	import init, { wasm_init } from "./pkg/my_wasm_crate.js";
	init().then(() => {
		wasm_init();
		// now do things as normal!
	});
</script>

Why?

inventory et al are cool, but can't yet be used when targeting wasm32-unknown-unknown or similar.

You might also like...
WebAssembly (Wasm) interpreter.

Continuous Integration Test Coverage Documentation Crates.io wasmi- WebAssembly (Wasm) Interpreter wasmi was conceived as a component of parity-ethere

Dependency solver for Elm, made in WebAssembly

Dependency solver for Elm, made in WebAssembly This repo holds a dependency solver for the elm ecosystem compiled to a WebAssembly module. The wasm mo

A simple code for checking crate 'prost' on WebAssembly (🦀 + 🕸️ = 💖)

rust-wasm-prost This repository is a simple code for checking crate 'prost' on WebAssembly ( 🦀 + 🕸️ = 💖 ). What is prost? prost is a Protocol Buffe

Version of Clue made to be compilable in WebAssembly (WIP)
Version of Clue made to be compilable in WebAssembly (WIP)

Clue is a programming language that compiles into Lua code with a syntax similar to languages like C or Rust. Clue tries to be almost as simple as Lua

Vite + Webassembly starter project
Vite + Webassembly starter project

Vite + Typescript+ Webassembly A starter project for you to create a blazingly fast web application Before getting started You need to get these prere

Mod_wasm - an extension module for the Apache HTTP Server (httpd) that enables the usage of WebAssembly (Wasm).
Mod_wasm - an extension module for the Apache HTTP Server (httpd) that enables the usage of WebAssembly (Wasm).

mod_wasm is an extension module for the Apache HTTP Server (httpd) that enables the usage of WebAssembly (Wasm). This module will allow to execute certain tasks in the backend in a very efficient and secure way.

Low level tooling for WebAssembly in JavaScript using wasm-tools

js-wasm-tools js-wasm-tools compiles some of the API of wasm-tools to JavaScript and WebAssembly via wasm-bindgen. This offers low level tooling for W

🚀 An OSS project to develop and run serverless applications on WebAssembly

Wasm Workers Server Wasm Workers Server (wws) is a framework to develop and run serverless applications server in WebAssembly. These applications are

An attempt to build full-featured WebAssembly-based monolith charts

Graphima Graphima (Greek: γράφημα) is an attempt to build full-featured WebAssembly-based monolith charts. See "Can I Use" WebAssembly for browser sup

Comments
  • Simplify the implementation of the crate and fix #1 at the same time.

    Simplify the implementation of the crate and fix #1 at the same time.

    Drops the paste crate and does not bother to use #[wasm_bindgen] to generate the exported init function. Instead, exports a plain extern "C" function and uses uses #[export = name] to set its name, as wasm-bindgen would have done.

    This is both simpler, and also does not require that the calling crate have wasm_bindgen as a direct dependency, so it fixes #1 at the same time.

    opened by kyren 3
  • Compile failure if the crate using the `wasm_init!` macro does not itself depend on wasm_bindgen.

    Compile failure if the crate using the `wasm_init!` macro does not itself depend on wasm_bindgen.

    I don't know how to solve this, but the #[wasm_bindgen] proc macro does not appear to support renaming the wasm_bindgen crate to something else, and refers to the module path wasm_bindgen in the expanded output. This causes wasm_init! to not compile if the caller does not itself depend on wasm_bindgen.

    I implemented a replacement for the inventory crate using ctor and wasm-init. Calling inventory::submit! without depending on wasm_bindgen produces get the following output:

    error[E0433]: failed to resolve: use of undeclared crate or module `wasm_bindgen`
      --> src/core/src/scripting/globals.rs:39:1
       |
    39 | / inventory::submit!(GlobalLib::new("serde global markers", |ctx| {
    40 | |     scripting::serde::global_markers(ctx);
    41 | |     Ok(())
    42 | | }));
       | |___^ use of undeclared crate or module `wasm_bindgen`
       |
       = note: this error originates in the attribute macro `$crate::__macrodeps::wasm_bindgen` which comes from the expansion of the macro `inventory::submit` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    error[E0425]: cannot find value `FUNCTION` in this scope
      --> src/core/src/scripting/globals.rs:39:1
       |
    39 | / inventory::submit!(GlobalLib::new("serde global markers", |ctx| {
    40 | |     scripting::serde::global_markers(ctx);
    41 | |     Ok(())
    42 | | }));
       | |___^ not found in this scope
       |
       = note: this error originates in the attribute macro `$crate::__macrodeps::wasm_bindgen` which comes from the expansion of the macro `inventory::submit` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    error[E0405]: cannot find trait `WasmDescribe` in this scope
      --> src/core/src/scripting/globals.rs:39:1
       |
    39 | / inventory::submit!(GlobalLib::new("serde global markers", |ctx| {
    40 | |     scripting::serde::global_markers(ctx);
    41 | |     Ok(())
    42 | | }));
       | |___^ not found in this scope
       |
       = note: this error originates in the attribute macro `$crate::__macrodeps::wasm_bindgen` which comes from the expansion of the macro `inventory::submit` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    error[E0425]: cannot find function `inform` in this scope
      --> src/core/src/scripting/globals.rs:39:1
       |
    39 | / inventory::submit!(GlobalLib::new("serde global markers", |ctx| {
    40 | |     scripting::serde::global_markers(ctx);
    41 | |     Ok(())
    42 | | }));
       | |___^ not found in this scope
       |
       = note: this error originates in the attribute macro `$crate::__macrodeps::wasm_bindgen` which comes from the expansion of the macro `inventory::submit` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    opened by kyren 2
Owner
Ruan Pearce-Authers
Recovering game developer.
Ruan Pearce-Authers
WebAssembly implementation from scratch in Safe Rust with zero dependencies

wain wain is a WebAssembly INterpreter written in Rust from scratch with zero dependencies. An implementation of WebAssembly. Features: No unsafe code

Linda_pp 328 Jan 2, 2023
A notebook app integrated with todo lists utility. Developed with Rust, WebAssembly, Yew and Trunk.

Flow.er A notebook app integrated with todo-list utility. Project flow.er is a Rust WASM app running in browser. Taking advantage of Yew and Trunk, it

null 45 Dec 31, 2022
witgen is a library to generate .wit files for WebAssembly in Rust

witgen witgen is a library to help you generate wit definitions in a wit file for WebAssembly. Using this lib in addition to wit-bindgen will help you

Coenen Benjamin 28 Nov 9, 2022
Build frontend browser apps with Rust + WebAssembly. Supports server side rendering.

Percy Build frontend browser apps with Rust + WebAssembly. Supports server side rendering. The Percy Book This README gives a light introduction to Pe

Chinedu Francis Nwafili 2.1k Jan 1, 2023
Rust bindings for Supabase JavaScript library via WebAssembly.

supabase-js-rs Rust bindings for Supabase JavaScript library via WebAssembly. Usage Add supabase-js-rs to Cargo.toml supabase-js-rs = { version = "0.1

Valery Stepanov 8 Jan 13, 2023
plugy empowers you to construct agnostic dynamic plugin systems using Rust and WebAssembly.

plugy plugy is a plugin system designed to enable the seamless integration of Rust-based plugins into your application. It provides a runtime environm

Geoffrey Mureithi 22 Aug 12, 2023
Code for my workshop "Production-ready WebAssembly with Rust" presented at RustLab 2023 in Florence

Workshop: Production-ready WebAssembly with Rust A workshop on Rust for WebAssembly by Alberto Schiabel (@jkomyno). ?? This workshop was first present

Alberto Schiabel 14 Nov 23, 2023
A 3D bin packing library in Rust/WebAssembly.

packme-wasm Demo https://packme.vercel.app This repository hosts an implementation of Dube, E., & Kanavathy L. (2006). Optimizing Three-Dimensional Bi

Ade Yahya Prasetyo 17 Feb 25, 2024
NPM package distributing biscuit in WebAssembly for web components

Biscuit playground This is an example application for Biscuit tokens, where you can manipulate tokens and their verification in your browser. build wi

null 0 Dec 30, 2021
`wasm-snip` replaces a WebAssembly function's body with an `unreachable`

wasm-snip wasm-snip replaces a Wasm function's body with an unreachable instruction. API Docs | Contributing | Chat Built with ?? ?? by The Rust and W

Rust and WebAssembly 177 Dec 28, 2022