diff --git a/kernel/src/handle.rs b/kernel/src/handle.rs index b141726c..99bc1d22 100644 --- a/kernel/src/handle.rs +++ b/kernel/src/handle.rs @@ -1,10 +1,18 @@ -use crate::interp::objects::{Object, OBJECTS}; +use spin::Lazy; + +use spin::{Mutex}; + +use crate::interp::objects::{Object,HandleTarget, TARGETS}; use { crate::arch::hardware_random_u64, alloc::vec::Vec, core::fmt::{self, Formatter}, }; + +use alloc::{ + collections::BTreeMap, +}; #[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)] pub struct OSHandle { pub id: u64, @@ -23,9 +31,9 @@ impl OSHandle { #[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)] pub struct Handle { - id: OSHandle, - perms: Permissions, - r#ref: usize, + pub id: OSHandle, + pub perms: Permissions, + pub r#ref: usize, } impl Handle { @@ -41,12 +49,10 @@ impl Handle { self.id.id } - pub fn get FnOnce(Option<&'a mut Object>) -> R>(&self,f: F) -> R{ - let l = OBJECTS; + pub fn get FnOnce(Option<&'a mut HandleTarget>) -> R>(&self, f: F) -> R { + let l = TARGETS; let mut olock = l.lock(); - let a = olock.get_mut(self.r#ref).and_then(|a|{ - a.as_mut() - }); + let a = olock.get_mut(self.r#ref).and_then(|a| a.as_mut()); return f(a); } } @@ -72,3 +78,8 @@ impl Permissions { } } } + +pub const GLOBALS: Lazy>> = Lazy::new(|| { + let mut globals = BTreeMap::new(); + Mutex::new(globals) +}); diff --git a/kernel/src/interp/host_functions.rs b/kernel/src/interp/host_functions.rs index 86607d35..ee9d898c 100644 --- a/kernel/src/interp/host_functions.rs +++ b/kernel/src/interp/host_functions.rs @@ -1,5 +1,5 @@ use { - crate::interp::{HFIDT, OBJECTS}, + crate::interp::{HFIDT, TARGETS}, alloc::string::String, log::trace, wasmi::{Caller, TypedFunc}, @@ -34,7 +34,14 @@ pub fn host_register_idt_handler( 0 } -use crate::interp::{objects::Object, Handle}; +use crate::{ + arch::hardware_random_u64, + handle::GLOBALS, + interp::{ + objects::{HandleTarget, Object}, + Handle, + }, +}; pub fn host_make_object( mut caller: Caller<'_, HostState>, @@ -54,15 +61,13 @@ pub fn host_make_object( name.push(ch); } trace!("Object Name {}", name); - let binding = OBJECTS; + let binding = TARGETS; let mut olock = binding.lock(); let hand = Handle::new(olock.len()); let obj = xml::XMLElement::new(name); - olock.push(Some(Object::Raw(obj))); - caller.data_mut().handles.push(hand); - // hand.into() - hand.as_u64().try_into().unwrap() + olock.push(Some(HandleTarget::Object(Object { xml: obj }))); + caller.data_mut().add_handle(hand).try_into().unwrap() } pub type WFIDT = TypedFunc<(), ()>; @@ -72,3 +77,33 @@ fn get_fn_from_wc(wc: WasmContext, function_name: String) -> WFIDT { .get_typed_func(wc.store, &function_name) .unwrap() } + +pub fn host_make_global(mut caller: Caller<'_, HostState>, h: i64) -> (u64, u64, u64, u64) { + let binding = GLOBALS; + let Some(hand): Option<&mut Option> = caller.data_mut().handles.get_mut(h as usize) else { + return (0,0,0,0); + }; + let Some(t) = hand.take() else { + return (0,0,0,0); + }; + let a = [hardware_random_u64(); 4]; + let mut l = binding.lock(); + l.insert(a, t); + return (a[0], a[1], a[2], a[3]); +} + +pub fn host_take_global(mut caller: Caller<'_, HostState>, a: u64, b: u64, c: u64, d: u64) -> i64 { + let binding = GLOBALS; + let mut l = binding.lock(); + let mut j: [u64; 4] = [0u64; 4]; + j[0] = a; + j[1] = b; + j[2] = c; + j[3] = d; + let Some(m) = l.remove::<[u64; 4]>({ + &j + }) else{ + return -1; + }; + caller.data_mut().add_handle(m) as i64 +} diff --git a/kernel/src/interp/mod.rs b/kernel/src/interp/mod.rs index 0193975d..276afccb 100644 --- a/kernel/src/interp/mod.rs +++ b/kernel/src/interp/mod.rs @@ -3,7 +3,7 @@ pub mod objects; use { crate::{ handle::{self, Handle}, - interp::{host_functions::host_make_object, objects::OBJECTS}, + interp::{host_functions::host_make_object, objects::TARGETS}, }, alloc::{string::String, vec::Vec}, hashbrown::HashMap, @@ -13,7 +13,12 @@ use { xml::XMLElement, }; // Seperate use statement -use alloc::vec; +use { + alloc::{fmt::format, format, vec}, + wasmi::Value, +}; + +use self::objects::HandleTarget; #[derive(Debug)] @@ -94,7 +99,20 @@ pub fn wasm() -> Result<(), wasmi::Error> { #[derive(Clone, Debug)] pub struct HostState { - handles: Vec, + handles: Vec>, +} + +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 { @@ -104,27 +122,60 @@ pub fn read_memory_address(caller: Caller<'_, HostState>, address: i32) -> i32 { } pub fn host_read_object_attribute( - caller: Caller<'_, HostState>, + mut caller: Caller<'_, HostState>, handle: i64, address_start: i32, length_of_string: i32, ) -> (i32, i32) { - { - let binding = OBJECTS; - let mut olock = binding.lock(); + let binding = TARGETS; + let mut olock = binding.lock(); - // olock.get(&handle); - } + // olock.get(&handle); let mem = caller.get_export("memory").unwrap().into_memory().unwrap(); - let mem_array = mem.data(&caller); + 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, ""); - (0, 0) + 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) -> Result { diff --git a/kernel/src/interp/objects.rs b/kernel/src/interp/objects.rs index 05d81112..47f998f6 100644 --- a/kernel/src/interp/objects.rs +++ b/kernel/src/interp/objects.rs @@ -1,35 +1,19 @@ -use alloc::{vec, vec::Vec}; +use alloc::{vec, vec::Vec, collections::BTreeMap}; use spin::{Lazy, Mutex}; -pub enum Object{ - Raw(xml::XMLElement) +use crate::handle::Handle; + +pub struct Object{ + pub xml: xml::XMLElement +} +pub enum HandleTarget{ + Object(Object) } -pub fn dump(o: Object) -> xml::XMLElement{ - match o{ - Object::Raw(x) => { - let mut e = xml::XMLElement::new("akern-internal-raw"); - e.children.push(x); - return e; - } - } -} +pub type HostTargets = Vec>; -pub fn restore(x: xml::XMLElement) -> Option{ - let s: &str = &x.name; - match s{ - "akern-internal-raw" => { - let f = x.children.get(0)?; - return Some(Object::Raw(f.clone())) - } - _ => None - } -} - -pub type HostObjects = Vec>; - -pub const OBJECTS: Lazy> = Lazy::new(|| { +pub const TARGETS: Lazy> = Lazy::new(|| { let mut obj = vec![]; Mutex::new(obj) });