Exposing globals to host application in WASM?

I'm converting a native driver into web assembly just to see if I can do it (because if so it would make things a lot easier for me). The driver requires a base address for the device, and then I can calculate register offsets. What is the safest way of exposing a global variable to the host that can then be updated to recompute register offsets?

A #[no_mangle] static will be exported from the WASM module:

#[no_mangle]
pub static mut BASE_ADDR: usize = 0;
(module
  (table (;0;) 1 1 funcref)
  (memory (;0;) 17)
  (global (;0;) (mut i32) (i32.const 1048576))
  (global (;1;) i32 (i32.const 1048576))
  (global (;2;) i32 (i32.const 1048580))
  (global (;3;) i32 (i32.const 1048580))
  (export "memory" (memory 0))
  (export "BASE_ADDR" (global 1))
  (export "__data_end" (global 2))
  (export "__heap_base" (global 3)))

Okay, but what if I want to do that safely without static mut? Can I just do a regular pub static or would Rust not export it then? Basically, I'm trying to do this:

#[no_mangle]
pub static mut BASE_ADDR: u64 = 0x00;
static REG1: u64 = BASE_ADDR + 0x04;

Such that when BASE_ADDR is updated, REG1 is recomputed as well.

An immutable static can't depend on the value of a mutable static.

Thanks. One last question about WASM: is there a way I can force-generate a trap without doing an illegal op? For instance, if I use WASM in an environment where I need to monitor for interrupts, is there a way I can "pause" the execution of a WASM module? Or do no WASM interpreter libraries allow that kind of thing?

You can use core::arch::wasm32::unreachable - Rust to generate a trap instruction. You could also potentially export a function that could be used for that from the host into the module.

It depends on your runtime. I use wasmer and they've got a wasmer::raise_user_trap() function which, when called from a host function, will raise a trap and abort the WebAssembly call.

You can later call RuntimeError::downcast() to extract the underlying error, giving you a way to differentiate between different the traps you may raise. I don't think you can use it as a mechanism for pausing execution though, the stack frames are probably thrown away and not resumable.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.