use alloc::string::String; use alloc::vec::Vec; use log::trace; use wasmi::Instance; use wasmi::{Caller, Func, Linker, Module, Store}; use xml::XMLElement; use crate::handle; #[derive(Debug)] pub struct WasmContext { pub proc_id: Option, pub instance: Instance, pub store: Store, } pub fn wasm() -> Result<(), wasmi::Error> { use wasmi::Config; use wasmi::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 {}; 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 version = instance.get_global(&store, "VERSION"); // trace!("Version: {:?}", version); let hello = instance.get_typed_func::<(), (i32, i32)>(&store, "start")?; let ret = hello.call(&mut store, ())?; trace!("Called _start got return of {:?}", ret); Ok(()) } #[derive(Clone, Debug)] pub struct HostState {} pub fn read_memory_address(caller: Caller<'_, HostState>, address: i32) -> i32 { trace!("Address: {}", address); // let obj = host_make_object(caller, 16, 23); 0 } use crate::kmain::OBJECTS; pub fn host_make_object( caller: Caller<'_, HostState>, address_start: i32, length_of_string: i32, ) -> i64 { trace!( "Called with addr {{ start {} length {} }}", address_start, length_of_string ); 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); } trace!("Object Name {}", name); let hand = handle::Handle::new(); { let binding = OBJECTS; let mut olock = binding.lock(); let obj = XMLElement::new(name); olock.insert(handle::Handle::new(), obj); } hand.into() } 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; use wasmi::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 {}; 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) }