Simple PoC with Wit and WASMA
This commit is contained in:
parent
808819adbf
commit
1c5a24c320
|
@ -0,0 +1 @@
|
||||||
|
/target
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"nixEnvSelector.nixFile": "${workspaceFolder}/shell.nix"
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,13 @@
|
||||||
|
workspace = { members = ["witguest"] }
|
||||||
|
[package]
|
||||||
|
name = "wittest"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
async-trait = "0.1.80"
|
||||||
|
tokio = { version = "1.37.0", features = ["full"] }
|
||||||
|
wasmtime = "19.0.2"
|
||||||
|
wasmtime-wasi = "19.0.2"
|
|
@ -0,0 +1,27 @@
|
||||||
|
let
|
||||||
|
rust_overlay = import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz");
|
||||||
|
pkgs = import <nixpkgs> { overlays = [ rust_overlay ]; };
|
||||||
|
|
||||||
|
rust = pkgs.rust-bin.stable.latest.default.override {
|
||||||
|
targets = [
|
||||||
|
"x86_64-unknown-linux-gnu"
|
||||||
|
"wasm32-unknown-unknown"
|
||||||
|
"wasm32-wasi"
|
||||||
|
];
|
||||||
|
extensions = [
|
||||||
|
"rust-analyzer"
|
||||||
|
"rust-src"
|
||||||
|
#"miri-preview"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
pkgs.mkShell.override {
|
||||||
|
stdenv = pkgs.stdenvAdapters.useMoldLinker pkgs.clangStdenv;
|
||||||
|
} rec {
|
||||||
|
buildInputs = [
|
||||||
|
rust
|
||||||
|
] ++ (with pkgs; [
|
||||||
|
cargo-component wasmtime wasm-tools
|
||||||
|
]);
|
||||||
|
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use wasmtime_wasi::WasiView;
|
||||||
|
|
||||||
|
wasmtime::component::bindgen!({
|
||||||
|
world: "example",
|
||||||
|
path: "witguest/wit/world.wit",
|
||||||
|
//tracing: true,
|
||||||
|
async: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
struct Imports {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WasiView for Imports {
|
||||||
|
fn table(&mut self) -> &mut wasmtime_wasi::ResourceTable {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ctx(&mut self) -> &mut wasmtime_wasi::WasiCtx {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl ExampleImports for Imports {
|
||||||
|
async fn host_test(&mut self,) -> wasmtime::Result<()> {
|
||||||
|
println!("This is the host saying hi from the guest!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> wasmtime::Result<()> {
|
||||||
|
// Instantiate the engine and store
|
||||||
|
let mut config = wasmtime::Config::default();
|
||||||
|
config.async_support(true);
|
||||||
|
|
||||||
|
let engine = wasmtime::Engine::new(&config)?;
|
||||||
|
let mut store = wasmtime::Store::new(&engine, Imports {});
|
||||||
|
|
||||||
|
// Load the component from disk
|
||||||
|
let bytes = std::fs::read("target/wasm32-wasi/debug/witguest.wasm")?;
|
||||||
|
let component = wasmtime::component::Component::new(&engine, bytes)?;
|
||||||
|
|
||||||
|
// Configure the linker
|
||||||
|
let mut linker = wasmtime::component::Linker::new(&engine);
|
||||||
|
wasmtime_wasi::bindings::Imports::add_to_linker(&mut linker, |s| s)?;
|
||||||
|
Example::add_to_linker(&mut linker, |s| s)?;
|
||||||
|
|
||||||
|
// Instantiate the component
|
||||||
|
println!("creating example");
|
||||||
|
let (example, _instance) = Example::instantiate_async(&mut store, &component, &linker).await?;
|
||||||
|
let result = example.call_hello_world(&mut store).await?;
|
||||||
|
println!("Guest says: {}", result);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"rust-analyzer.check.overrideCommand": [
|
||||||
|
"cargo",
|
||||||
|
"component",
|
||||||
|
"check",
|
||||||
|
"--workspace",
|
||||||
|
"--all-targets",
|
||||||
|
"--message-format=json"
|
||||||
|
],
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
name = "witguest"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wit-bindgen = { version = "0.24.0", default-features = false, features = ["realloc"] }
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[package.metadata.component]
|
||||||
|
package = "component:witguest"
|
||||||
|
|
||||||
|
[package.metadata.component.dependencies]
|
|
@ -0,0 +1,86 @@
|
||||||
|
// Generated by `wit-bindgen` 0.18.0. DO NOT EDIT!
|
||||||
|
#[allow(unused_unsafe, clippy::all)]
|
||||||
|
pub fn host_test(){
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use wit_bindgen::rt::{alloc, vec::Vec, string::String};
|
||||||
|
unsafe {
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[link(wasm_import_module = "$root")]
|
||||||
|
extern "C" {
|
||||||
|
#[link_name = "host-test"]
|
||||||
|
fn wit_import();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
fn wit_import(){ unreachable!() }
|
||||||
|
wit_import();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const _: () = {
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[export_name = "hello-world"]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
unsafe extern "C" fn __export_hello_world() -> i32 {
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use wit_bindgen::rt::{alloc, vec::Vec, string::String};
|
||||||
|
|
||||||
|
// Before executing any other code, use this function to run all static
|
||||||
|
// constructors, if they have not yet been run. This is a hack required
|
||||||
|
// to work around wasi-libc ctors calling import functions to initialize
|
||||||
|
// the environment.
|
||||||
|
//
|
||||||
|
// This functionality will be removed once rust 1.69.0 is stable, at which
|
||||||
|
// point wasi-libc will no longer have this behavior.
|
||||||
|
//
|
||||||
|
// See
|
||||||
|
// https://github.com/bytecodealliance/preview2-prototyping/issues/99
|
||||||
|
// for more details.
|
||||||
|
#[cfg(target_arch="wasm32")]
|
||||||
|
wit_bindgen::rt::run_ctors_once();
|
||||||
|
|
||||||
|
let result0 = <_GuestImpl as Guest>::hello_world();
|
||||||
|
let ptr1 = _RET_AREA.0.as_mut_ptr() as i32;
|
||||||
|
let vec2 = (result0.into_bytes()).into_boxed_slice();
|
||||||
|
let ptr2 = vec2.as_ptr() as i32;
|
||||||
|
let len2 = vec2.len() as i32;
|
||||||
|
::core::mem::forget(vec2);
|
||||||
|
*((ptr1 + 4) as *mut i32) = len2;
|
||||||
|
*((ptr1 + 0) as *mut i32) = ptr2;
|
||||||
|
ptr1
|
||||||
|
}
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[export_name = "cabi_post_hello-world"]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
unsafe extern "C" fn __post_return_hello_world(arg0: i32,) {
|
||||||
|
let l0 = *((arg0 + 0) as *const i32);
|
||||||
|
let l1 = *((arg0 + 4) as *const i32);
|
||||||
|
wit_bindgen::rt::dealloc(l0, (l1) as usize, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
use super::Component as _GuestImpl;
|
||||||
|
pub trait Guest {
|
||||||
|
fn hello_world() -> wit_bindgen::rt::string::String;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use wit_bindgen::rt::{alloc, vec::Vec, string::String};
|
||||||
|
|
||||||
|
#[repr(align(4))]
|
||||||
|
struct _RetArea([u8; 8]);
|
||||||
|
static mut _RET_AREA: _RetArea = _RetArea([0; 8]);
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[link_section = "component-type:example"]
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 201] = [0, 97, 115, 109, 13, 0, 1, 0, 0, 25, 22, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 4, 0, 7, 77, 1, 65, 2, 1, 65, 4, 1, 64, 0, 1, 0, 3, 0, 9, 104, 111, 115, 116, 45, 116, 101, 115, 116, 1, 0, 1, 64, 0, 0, 115, 4, 0, 11, 104, 101, 108, 108, 111, 45, 119, 111, 114, 108, 100, 1, 1, 4, 1, 26, 99, 111, 109, 112, 111, 110, 101, 110, 116, 58, 119, 105, 116, 103, 117, 101, 115, 116, 47, 101, 120, 97, 109, 112, 108, 101, 4, 0, 11, 13, 1, 0, 7, 101, 120, 97, 109, 112, 108, 101, 3, 0, 0, 0, 70, 9, 112, 114, 111, 100, 117, 99, 101, 114, 115, 1, 12, 112, 114, 111, 99, 101, 115, 115, 101, 100, 45, 98, 121, 2, 13, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 6, 48, 46, 50, 49, 46, 48, 16, 119, 105, 116, 45, 98, 105, 110, 100, 103, 101, 110, 45, 114, 117, 115, 116, 6, 48, 46, 49, 56, 46, 48];
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
pub fn __link_section() {}
|
|
@ -0,0 +1,13 @@
|
||||||
|
mod bindings;
|
||||||
|
|
||||||
|
use bindings::Guest;
|
||||||
|
|
||||||
|
struct Component;
|
||||||
|
|
||||||
|
impl Guest for Component {
|
||||||
|
/// Say hello!
|
||||||
|
fn hello_world() -> String {
|
||||||
|
bindings::host_test();
|
||||||
|
"Hello, World!".to_string()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package component:witguest;
|
||||||
|
|
||||||
|
/// An example world for the component to target.
|
||||||
|
world example {
|
||||||
|
import host-test: func();
|
||||||
|
export hello-world: func() -> string;
|
||||||
|
}
|
Loading…
Reference in New Issue