/* * wasm-ir - Intermediate Representation of WebAssembly * Copyright © 2019-2022 Blue Forest * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use wasmtime::*; use wasmtime_wasi::WasiCtx; use wasmtime_wasi::sync::WasiCtxBuilder; use wasmtime_wasi::sync::net::TcpStream; use cap_std; use std::net; use std::net::TcpListener; pub struct Embedder { pub engine: Engine, pub linker: Linker, pub listener: TcpListener, pub store: Store, } impl Embedder { pub fn new(port: &str) -> Self { let listener = TcpListener::bind(format!("127.0.0.1:{}", port)).unwrap(); let stream = cap_std::net::TcpStream::from_std( net::TcpStream::connect(format!("127.0.0.1:{}", port)).unwrap() ); let wasi_ctx = WasiCtxBuilder::new() .stdout(Box::new(TcpStream::from_cap_std(stream))) .build(); let engine = Engine::default(); let mut linker = Linker::new(&engine); wasmtime_wasi::add_to_linker(&mut linker, |cx| cx).unwrap(); let store = Store::new(&engine, wasi_ctx); Embedder{ listener, engine, linker, store } } pub fn define_from_instance(&mut self, instance: Instance, name: &str) { let exported = instance.get_export(&mut self.store, name).unwrap(); self.linker.define("env", name, exported).unwrap(); } pub fn instantiate(&mut self, binary: Vec) -> Instance { let module = Module::new(&self.engine, binary).unwrap(); self.linker.instantiate( &mut self.store, &module, ).unwrap() } pub fn run(&mut self, binary: Vec) { let start = self.instantiate(binary).get_typed_func::<(), (), _>( &mut self.store, "_start" ).unwrap(); start.call(&mut self.store, ()).unwrap(); } }