It works! It works! With lots of hacks it works!

This commit is contained in:
Graham Kelly 2023-04-12 20:35:57 -04:00
parent 2a7f15239e
commit 4e2819f025
4 changed files with 134 additions and 53 deletions

View file

@ -1,10 +1,18 @@
use crate::interp::objects::{Object, OBJECTS}; use spin::Lazy;
use spin::{Mutex};
use crate::interp::objects::{Object,HandleTarget, TARGETS};
use { use {
crate::arch::hardware_random_u64, crate::arch::hardware_random_u64,
alloc::vec::Vec, alloc::vec::Vec,
core::fmt::{self, Formatter}, core::fmt::{self, Formatter},
}; };
use alloc::{
collections::BTreeMap,
};
#[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)] #[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)]
pub struct OSHandle { pub struct OSHandle {
pub id: u64, pub id: u64,
@ -23,9 +31,9 @@ impl OSHandle {
#[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)] #[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)]
pub struct Handle { pub struct Handle {
id: OSHandle, pub id: OSHandle,
perms: Permissions, pub perms: Permissions,
r#ref: usize, pub r#ref: usize,
} }
impl Handle { impl Handle {
@ -41,12 +49,10 @@ impl Handle {
self.id.id self.id.id
} }
pub fn get<R, F: for <'a> FnOnce(Option<&'a mut Object>) -> R>(&self,f: F) -> R{ pub fn get<R, F: for<'a> FnOnce(Option<&'a mut HandleTarget>) -> R>(&self, f: F) -> R {
let l = OBJECTS; let l = TARGETS;
let mut olock = l.lock(); let mut olock = l.lock();
let a = olock.get_mut(self.r#ref).and_then(|a|{ let a = olock.get_mut(self.r#ref).and_then(|a| a.as_mut());
a.as_mut()
});
return f(a); return f(a);
} }
} }
@ -72,3 +78,8 @@ impl Permissions {
} }
} }
} }
pub const GLOBALS: Lazy<Mutex<BTreeMap<[u64; 4], Handle>>> = Lazy::new(|| {
let mut globals = BTreeMap::new();
Mutex::new(globals)
});

View file

@ -1,5 +1,5 @@
use { use {
crate::interp::{HFIDT, OBJECTS}, crate::interp::{HFIDT, TARGETS},
alloc::string::String, alloc::string::String,
log::trace, log::trace,
wasmi::{Caller, TypedFunc}, wasmi::{Caller, TypedFunc},
@ -34,7 +34,14 @@ pub fn host_register_idt_handler(
0 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( pub fn host_make_object(
mut caller: Caller<'_, HostState>, mut caller: Caller<'_, HostState>,
@ -54,15 +61,13 @@ pub fn host_make_object(
name.push(ch); name.push(ch);
} }
trace!("Object Name {}", name); trace!("Object Name {}", name);
let binding = OBJECTS; let binding = TARGETS;
let mut olock = binding.lock(); let mut olock = binding.lock();
let hand = Handle::new(olock.len()); let hand = Handle::new(olock.len());
let obj = xml::XMLElement::new(name); let obj = xml::XMLElement::new(name);
olock.push(Some(Object::Raw(obj))); olock.push(Some(HandleTarget::Object(Object { xml: obj })));
caller.data_mut().handles.push(hand); caller.data_mut().add_handle(hand).try_into().unwrap()
// hand.into()
hand.as_u64().try_into().unwrap()
} }
pub type WFIDT = TypedFunc<(), ()>; 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) .get_typed_func(wc.store, &function_name)
.unwrap() .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<Handle>> = 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
}

View file

@ -3,7 +3,7 @@ pub mod objects;
use { use {
crate::{ crate::{
handle::{self, Handle}, handle::{self, Handle},
interp::{host_functions::host_make_object, objects::OBJECTS}, interp::{host_functions::host_make_object, objects::TARGETS},
}, },
alloc::{string::String, vec::Vec}, alloc::{string::String, vec::Vec},
hashbrown::HashMap, hashbrown::HashMap,
@ -13,7 +13,12 @@ use {
xml::XMLElement, xml::XMLElement,
}; };
// Seperate use statement // Seperate use statement
use alloc::vec; use {
alloc::{fmt::format, format, vec},
wasmi::Value,
};
use self::objects::HandleTarget;
#[derive(Debug)] #[derive(Debug)]
@ -94,7 +99,20 @@ pub fn wasm() -> Result<(), wasmi::Error> {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct HostState { pub struct HostState {
handles: Vec<Handle>, 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 { 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( pub fn host_read_object_attribute(
caller: Caller<'_, HostState>, mut caller: Caller<'_, HostState>,
handle: i64, handle: i64,
address_start: i32, address_start: i32,
length_of_string: i32, length_of_string: i32,
) -> (i32, i32) { ) -> (i32, i32) {
{ let binding = TARGETS;
let binding = OBJECTS;
let mut olock = binding.lock(); let mut olock = binding.lock();
// olock.get(&handle); // olock.get(&handle);
}
let mem = caller.get_export("memory").unwrap().into_memory().unwrap(); 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(); let mut name = String::new();
for i in address_start..(address_start + length_of_string) { for i in address_start..(address_start + length_of_string) {
let ch = mem_array[i as usize] as char; let ch = mem_array[i as usize] as char;
name.push(ch); 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<u8>) -> Result<WasmContext, wasmi::Error> { pub fn build_wasm_context(bytes: Vec<u8>) -> Result<WasmContext, wasmi::Error> {

View file

@ -1,35 +1,19 @@
use alloc::{vec, vec::Vec}; use alloc::{vec, vec::Vec, collections::BTreeMap};
use spin::{Lazy, Mutex}; use spin::{Lazy, Mutex};
pub enum Object{ use crate::handle::Handle;
Raw(xml::XMLElement)
pub struct Object{
pub xml: xml::XMLElement
}
pub enum HandleTarget{
Object(Object)
} }
pub fn dump(o: Object) -> xml::XMLElement{ pub type HostTargets = Vec<Option<HandleTarget>>;
match o{
Object::Raw(x) => {
let mut e = xml::XMLElement::new("akern-internal-raw");
e.children.push(x);
return e;
}
}
}
pub fn restore(x: xml::XMLElement) -> Option<Object>{ pub const TARGETS: Lazy<Mutex<HostTargets>> = Lazy::new(|| {
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<Option<Object>>;
pub const OBJECTS: Lazy<Mutex<HostObjects>> = Lazy::new(|| {
let mut obj = vec![]; let mut obj = vec![];
Mutex::new(obj) Mutex::new(obj)
}); });