WebAssembly interpreter for Daisy Seed - A minimal no_std wrapper around wasmi for embedded ARM Cortex-M7F targets.
This library provides a C-compatible FFI interface to the wasmi WebAssembly interpreter, compiled specifically for the Daisy Seed platform (ARM Cortex-M7F, thumbv7em-none-eabihf).
Unlike wasmi's official C API (which requires std), this wrapper:
- ✅ Compiles for bare-metal ARM with
no_std - ✅ Includes a simple bump allocator (512KB heap)
- ✅ Provides C-compatible functions callable from C++
- ✅ Uses wasmi natively (proven to work on ARM)
./build.shThis creates:
target/thumbv7em-none-eabihf/release/libwasmi_daisy.a- Static librarywasmi_daisy.h- C header file
# Add include path
C_INCLUDES += -I/path/to/wasmi-daisy
# Add library to linker flags
LDFLAGS += /path/to/wasmi-daisy/target/thumbv7em-none-eabihf/release/libwasmi_daisy.a#include "wasmi_daisy.h"See example.cpp for a complete usage example.
WasmiEngine* wasmi_engine_new()- Create enginevoid wasmi_engine_delete(WasmiEngine*)- Delete engine
WasmiStore* wasmi_store_new(const WasmiEngine*)- Create storevoid wasmi_store_delete(WasmiStore*)- Delete store
WasmiModule* wasmi_module_new(engine, bytes, len)- Load wasm modulevoid wasmi_module_delete(WasmiModule*)- Delete module
WasmiInstance* wasmi_instance_new(store, module)- Instantiate modulevoid wasmi_instance_delete(WasmiInstance*)- Delete instance
WasmiFunc* wasmi_instance_get_func(store, instance, name, name_len)- Get exported functionint32_t wasmi_func_call_i32_i32_to_i32(store, func, arg0, arg1)- Call functionvoid wasmi_func_delete(WasmiFunc*)- Delete function handle
The library uses the Jaffx SDRAM allocator for all memory allocations. This gives you:
- ✅ Proper memory management (malloc/free with coalescing)
- ✅ Full 64MB SDRAM available for WebAssembly modules
- ✅ No fixed heap size - grows as needed
- ✅ Memory can be freed and reused
You must provide these extern "C" functions in your application:
extern "C" {
void* jaffx_sdram_malloc(size_t size) {
return Jaffx::mSDRAM.malloc(size);
}
void jaffx_sdram_free(void* ptr) {
Jaffx::mSDRAM.free(ptr);
}
}These delegate to the Jaffx SDRAM manager which handles all allocation bookkeeping.
- Target: thumbv7em-none-eabihf (ARM Cortex-M7F with hardware FPU)
- Optimization: Size-optimized (
opt-level = "z") - LTO: Enabled for smaller binary size
- Dependencies: wasmi (no_std mode)
The official wasmi C API (wasmi_c_api) fails to build for ARM because:
- It builds as
cdylib/staticlibcrate type - This triggers a bug in the
spinv0.9.8 dependency - The bug causes missing Rust prelude imports for certain ARM targets
This wrapper solves the problem by:
- Using wasmi directly as a Rust library dependency
- Building as a
staticlibwithout the intermediatewasmi_c_apilayer - Providing our own FFI bindings
The Jaffx SDRAM allocator provides:
- ✅ Dynamic allocation and deallocation
- ✅ Automatic coalescing of free blocks
- ✅ Efficient memory reuse
- ✅ Full 64MB SDRAM address space
- ✅ Proper bookkeeping with metadata
No configuration needed - the Jaffx SDRAM manager handles everything!
This wrapper follows the same license as wasmi (MIT/Apache-2.0).
The compiled libwasmi_daisy.a is approximately 1-2MB. This includes:
- wasmi interpreter
- WebAssembly parser
- Our FFI wrapper
- Allocator implementation
Use arm-none-eabi-size on your final binary to see actual memory usage.