Skip to content

chicken and the egg linker.func design #2007

@softprops

Description

@softprops

I'm running into a problem with the current Linker.func api as it relates to the wiring of a wasm runtime.

The following illustrates a problem I'm having where in order to instantiate a Module, one must configure a linker's functions. In my case this runtime is expected to provide a an implementation of a number of module functions. When they are not defined wasi's call to instantiate a Module fails with very useful error reporting describing the missing implementation and its type signature. However in order to define those linker functions I would require the instantiated modules Memory reference if I understand this system currently.

I'm new to wasm so I may be missing something here but presumably the example below is a more helpful and fill the gaps I'm not sure how to describe yet.

use wasmtime::*;
use wasmtime_wasi::{Wasi, WasiCtxBuilder};
use byteorder::ByteOrder;

let engine = Engine::default();
let store = Store::new(&engine);
let mut linker = Linker::new(&store);
let wasi = Wasi::new(
      &store,
     WasiCtxBuilder::new()
           .inherit_stdout()
           .inherit_stderr()
           .build()?
);
wasi.add_to_linker(&mut linker)?;

// the egg exists here. The egg needs the a reference chicken's memory
linker.func(
       "mod_name",
       "fn_name",
        |offset_arg0: i32| {
           // performs some computation then updates the instances Memory
            let some_computed_result: u32 = ...;
            unsafe {
                    byteorder::LittleEndian::write_u32(
                        &mut memory.data_unchecked_mut()[offset_arg0 as usize..],
                        some_computed_result,
                    );
           }
           0
        },
 )?;
      
// the chicken is born here the chicken can not be born without the linker being defining the implementation
// of `mod_name::fn_name`
let instance = linker.instantiate(&Module::from_file(&engine,"path/to/app.wasm")?)?;

let memory = instance
   .get_memory("memory")
   .expect("all instances should have memory. this one does not");

I'm basing this Rust application off of an implementation in go-wasmtime which orchestrates this all in the the setup of of a structs NewFoo func where the reference to memory can be nil at the time of link definition. This is made slightly more challenging with rusts memory module and references to "self" and/or any external closure references inside linker.func()

I can fill in more concrete details if needed but I'm wondering if it's clear I'm missing something very fundamental right out of the gate with wasmtime's expected api usage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions