forked from AbleOS/ableos
252 lines
6.5 KiB
Rust
252 lines
6.5 KiB
Rust
mod host_functions;
|
|
pub mod objects;
|
|
use {
|
|
crate::{
|
|
handle::{self, Handle},
|
|
interp::{host_functions::host_make_object, objects::TARGETS},
|
|
},
|
|
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::{fmt::format, format, vec},
|
|
wasmi::Value,
|
|
};
|
|
|
|
use self::objects::HandleTarget;
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct WasmContext {
|
|
pub proc_id: Option<u64>,
|
|
pub instance: Instance,
|
|
pub store: Store<HostState>,
|
|
}
|
|
|
|
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 = <Linker<HostState>>::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<Option<Handle>>,
|
|
}
|
|
|
|
impl HostState {
|
|
pub fn add_handle(&mut self, hand: Handle) -> usize {
|
|
for (i, h) in self.handles.iter_mut().enumerate() {
|
|
if let None = h {
|
|
*h = Some(hand);
|
|
return i;
|
|
}
|
|
}
|
|
self.handles.push(Some(hand));
|
|
return (self.handles.len() - 1);
|
|
}
|
|
}
|
|
|
|
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(
|
|
mut caller: Caller<'_, HostState>,
|
|
handle: i64,
|
|
address_start: i32,
|
|
length_of_string: i32,
|
|
) -> (i32, i32) {
|
|
let binding = TARGETS;
|
|
let mut olock = binding.lock();
|
|
|
|
// olock.get(&handle);
|
|
|
|
let mem = caller.get_export("memory").unwrap().into_memory().unwrap();
|
|
let mem_array = mem.data_mut(&mut 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);
|
|
}
|
|
let Some(Some(a)) = caller.data().handles.get(handle as usize) else {
|
|
return (0,0);
|
|
};
|
|
let Some(Some(HandleTarget::Object(o))) = olock.get(a.r#ref) else{
|
|
return (0,0);
|
|
};
|
|
let Some(r) = o.xml.attributes.iter().find(|a|{
|
|
let f = format!("{:?}",a);
|
|
f.contains(&format!("Attribute{{ name: \"{}",name))
|
|
})else{
|
|
return (0,0);
|
|
};
|
|
let f = format!("{:?}", r);
|
|
let p = format!("Attribute{{ name: \"{}\", value: \"", name);
|
|
let s = format!("\" }}");
|
|
let h = f.replace(&p, "").replace(&s, "");
|
|
|
|
let i = vec![Value::I32(h.len().try_into().unwrap())];
|
|
let mut o = vec![Value::I32(0)];
|
|
|
|
let a = caller
|
|
.get_export("malloc")
|
|
.unwrap()
|
|
.into_func()
|
|
.unwrap()
|
|
.call(&mut caller, &i, &mut o);
|
|
let mem_array = mem.data_mut(&mut caller);
|
|
|
|
let Value::I32(a) = o[0] else{
|
|
panic!("invalid malloc");
|
|
};
|
|
|
|
for (s, b) in h.clone().into_bytes().iter().enumerate() {
|
|
mem_array[(a as usize) + s] = *b;
|
|
}
|
|
|
|
(a, h.len().try_into().unwrap())
|
|
}
|
|
|
|
pub fn build_wasm_context(bytes: Vec<u8>) -> Result<WasmContext, 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 = <Linker<HostState>>::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<usize, WCFunction>;
|
|
pub struct WCFunction {
|
|
wc: WasmContext,
|
|
function: TypedFunc<(), ()>,
|
|
}
|
|
|
|
pub static HFIDT: Lazy<Mutex<HostFunctionIDT>> = Lazy::new(|| {
|
|
let mut hfidt = HashMap::new();
|
|
|
|
Mutex::new(hfidt)
|
|
});
|