#assemblyscript #wasm-module #wasmer #helper

wasmer-as

Helpers to read and write memory in AssemblyScript wasm modules executing in wasmer-runtime

10 releases

0.4.0 Jul 18, 2021
0.3.0-alpha.4 May 19, 2020
0.3.0-alpha.2 Mar 19, 2020
0.2.2 Feb 25, 2020
0.1.2 Jan 24, 2020

#952 in WebAssembly

24 downloads per month

Apache-2.0

10KB
57 lines

Helpers for dealing with assemblyscript memory inside wasmer-runtime

use std::error::Error;
use wasmer::*;
use wasmer_as::{AsmScriptRead, AsmScriptStringPtr};

#[derive(Clone)]
struct Env {
    memory: LazyInit<Memory>,
}

impl WasmerEnv for Env {
    fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> {
        self.memory.initialize(
            instance
                .exports
                .get_memory("memory")
                .map_err(HostEnvInitError::from)?
                .clone(),
        );
        Ok(())
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    let wasm_bytes = include_bytes!(concat!(
        env!("CARGO_MANIFEST_DIR"),
        "/test-wasm/build/optimized.wasm"
    ));
    let store = Store::default();
    let module = Module::new(&store, wasm_bytes)?;

    let env = Env {
        memory: LazyInit::default(),
    };

    let import_object = imports! {
        "env" => {
            "abort" => Function::new_native_with_env(&store, env, abort),
        },
    };

    let instance = Instance::new(&module, &import_object)?;

    // for the test we use simple function returning constant string:
    //
    // export function getString(): string {
    //   return "TheString";
    // }
    let get_string = instance.exports.get_function("getString")?;

    let results = get_string.call(&[])?;

    let str_ptr = results.first().expect("get pointer");
    let str_ptr = AsmScriptStringPtr::new(str_ptr.unwrap_i32() as u32);

    let memory = instance.exports.get_memory("memory").expect("get memory");
    let string = str_ptr.read(memory)?;

    assert_eq!(string, "$¢ह한𝌆");

    Ok(())
}

// if get_string throws an exception abort for some reason is being called
fn abort(
    env: &Env,
    message: AsmScriptStringPtr,
    filename: AsmScriptStringPtr,
    line: i32,
    col: i32
) {
    let memory = env.memory.get_ref().expect("initialized memory");
    let message = message.read(memory).unwrap();
    let filename = filename.read(memory).unwrap();
    eprintln!("Error: {} at {}:{} col: {}", message, filename, line, col);
}

Dependencies

~6–15MB
~201K SLoC