mod host_functions; mod objects; use { crate::{ handle::{self, Handle}, interp::{host_functions::host_make_object, objects::OBJECTS}, }, alloc::{string::String, vec::Vec}, hashbrown::HashMap, log::trace, spin::{Lazy, Mutex}, wasmi::{Caller, Error, Func, Instance, Linker, Module, Store, TypedFunc}, xml::XMLElement, }; // Seperate use statement use alloc::vec; #[derive(Debug)] pub struct WasmContext { pub proc_id: Option, pub instance: Instance, pub store: Store, } pub fn wasm() -> Result<(), wasmi::Error> { use wasmi::{Config, Engine}; let mut conf = Config::default(); conf.wasm_bulk_memory(true); // conf., let engine = Engine::new(&conf); // trace!("Engine constructed"); // let wasm = include_bytes!("../../wasm_syscall_test.wasm"); let wasm = include_bytes!("../../../test.wasm"); // trace!("Loading WASM binary"); let module = Module::new(&engine, &wasm[..]).unwrap(); // trace!("Constructing wasm module"); let hs = HostState { handles: vec![] }; let mut store = Store::new(&engine, hs); // trace!("constructing host store"); let read_mem_addr = Func::wrap( &mut store, |caller: Caller<'_, HostState>, param: i32| -> i32 { read_memory_address(caller, param) }, ); let mut linker = >::new(&engine); linker.define( "host", "read_mem_addr", Func::wrap( &mut store, |caller: Caller<'_, HostState>, param: i32| -> i32 { read_memory_address(caller, param) }, ), )?; linker.define( "host", "register_idt_handler", Func::wrap(&mut store, host_functions::host_register_idt_handler), )?; linker.define( "host", "read_object_attribute", Func::wrap(&mut store, host_read_object_attribute), )?; linker.define( "host", "create_object", Func::wrap(&mut store, host_make_object), )?; let instance = linker .instantiate(&mut store, &module)? .ensure_no_start(&mut store)?; let version = instance.get_global(&store, "VERSION"); // trace!("Version: {:?}", version); let hello = instance.get_typed_func::<(), i64>(&store, "start")?; let ret = hello.call(&mut store, ())?; trace!("Called start got return of {:?}", ret); Ok(()) } #[derive(Clone, Debug)] pub struct HostState { handles: Vec, } pub fn read_memory_address(caller: Caller<'_, HostState>, address: i32) -> i32 { trace!("Address: {}", address); // let obj = host_make_object(caller, 16, 23); 0 } pub fn host_read_object_attribute( caller: Caller<'_, HostState>, handle: i64, address_start: i32, length_of_string: i32, ) -> (i32, i32) { { let binding = OBJECTS; let mut olock = binding.lock(); // olock.get(&handle); } let mem = caller.get_export("memory").unwrap().into_memory().unwrap(); let mem_array = mem.data(&caller); let mut name = String::new(); for i in address_start..(address_start + length_of_string) { let ch = mem_array[i as usize] as char; name.push(ch); } (0, 0) } pub fn build_wasm_context(bytes: Vec) -> Result { use wasmi::{Config, Engine}; let mut conf = Config::default(); conf.wasm_bulk_memory(true); // conf., let engine = Engine::new(&conf); // trace!("Engine constructed"); // let wasm = include_bytes!("../../wasm_syscall_test.wasm"); let wasm = include_bytes!("../../../test.wasm"); // trace!("Loading WASM binary"); let module = Module::new(&engine, &wasm[..]).unwrap(); // trace!("Constructing wasm module"); let hs = HostState { handles: vec![] }; let mut store = Store::new(&engine, hs); // trace!("constructing host store"); let read_mem_addr = Func::wrap( &mut store, |caller: Caller<'_, HostState>, param: i32| -> i32 { read_memory_address(caller, param) }, ); let mut linker = >::new(&engine); linker.define( "host", "read_mem_addr", Func::wrap( &mut store, |caller: Caller<'_, HostState>, param: i32| -> i32 { read_memory_address(caller, param) }, ), )?; linker.define( "host", "read_object_attribute", Func::wrap(&mut store, host_read_object_attribute), )?; linker.define( "host", "create_object", Func::wrap(&mut store, host_make_object), )?; let instance = linker .instantiate(&mut store, &module)? .ensure_no_start(&mut store)?; let wc = WasmContext { instance, store, proc_id: None, }; Ok(wc) } pub type HostFunctionIDT = HashMap; pub struct WCFunction { wc: WasmContext, function: TypedFunc<(), ()>, } pub static HFIDT: Lazy> = Lazy::new(|| { let mut hfidt = HashMap::new(); Mutex::new(hfidt) });