Improved context data

This commit is contained in:
Syrus Akbary
2018-10-22 21:03:43 +02:00
parent 4ab26226f9
commit 037f76e3b1
2 changed files with 35 additions and 42 deletions

View File

@ -82,7 +82,7 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> {
}); });
let main: fn(&webassembly::VmCtx) = get_instance_function!(instance, func_index); let main: fn(&webassembly::VmCtx) = get_instance_function!(instance, func_index);
let context = instance.generate_context(); let context = instance.generate_context();
main(context); main(&context);
Ok(()) Ok(())
} }

View File

@ -68,27 +68,10 @@ fn get_function_addr(
// (base as usize + offset) as _ // (base as usize + offset) as _
// } // }
/// Zero-sized, non-instantiable type.
#[derive(Debug)]
pub enum VmCtx {}
impl VmCtx {
pub fn data(&self) -> &VmCtxData {
let heap_ptr = self as *const _ as *const VmCtxData;
unsafe { &*heap_ptr.sub(1) }
}
/// This is safe because the offset is 32 bits and thus
/// cannot extend out of the guarded wasm memory.
pub fn fastpath_offset_ptr<T>(&self, offset: u32) -> *const T {
let heap_ptr = self as *const _ as *const u8;
unsafe { heap_ptr.add(offset as usize) as *const T }
}
}
// #[derive(Debug)] // #[derive(Debug)]
#[repr(C)] #[repr(C)]
pub struct VmCtxData<'phantom> { pub struct VmCtx<'phantom> {
pub user_data: UserData, pub user_data: UserData,
globals: UncheckedSlice<u8>, globals: UncheckedSlice<u8>,
memories: UncheckedSlice<UncheckedSlice<u8>>, memories: UncheckedSlice<UncheckedSlice<u8>>,
@ -240,9 +223,13 @@ impl Instance {
}, },
RelocationType::CurrentMemory => { RelocationType::CurrentMemory => {
current_memory as isize current_memory as isize
// panic!("current memory not yet implemented");
// unimplemented!()
}, },
RelocationType::GrowMemory => { RelocationType::GrowMemory => {
grow_memory as isize grow_memory as isize
// panic!("Grow memory not yet implemented");
// unimplemented!()
}, },
_ => unimplemented!() _ => unimplemented!()
// RelocationType::Intrinsic(name) => { // RelocationType::Intrinsic(name) => {
@ -518,33 +505,33 @@ impl Instance {
} }
} }
pub fn generate_context(&mut self) -> &VmCtx { pub fn generate_context(&mut self) -> VmCtx {
let mut memories: Vec<UncheckedSlice<u8>> = self.memories.iter().map(|mem| mem[..].into()).collect(); let mut memories: Vec<UncheckedSlice<u8>> = self.memories.iter().map(|mem| mem[..].into()).collect();
let tables: Vec<BoundedSlice<usize>> = self.tables.iter().map(|table| table[..].into()).collect(); let tables: Vec<BoundedSlice<usize>> = self.tables.iter().map(|table| table[..].into()).collect();
let globals: UncheckedSlice<u8> = self.globals[..].into(); let globals: UncheckedSlice<u8> = self.globals[..].into();
assert!(memories.len() >= 1, "modules must have at least one memory"); // assert!(memories.len() >= 1, "modules must have at least one memory");
// the first memory has a space of `mem::size_of::<VmCtxData>()` rounded // the first memory has a space of `mem::size_of::<VmCtxData>()` rounded
// up to the 4KiB before it. We write the VmCtxData into that. // up to the 4KiB before it. We write the VmCtxData into that.
let instance = self.clone(); let instance = self.clone();
let data = VmCtxData { let data = VmCtx {
globals: globals, globals: globals,
memories: memories[1..].into(), memories: memories[..].into(),
tables: tables[..].into(), tables: tables[..].into(),
user_data: UserData { user_data: UserData {
// process, // process,
instance, instance: instance,
}, },
phantom: PhantomData, phantom: PhantomData,
}; };
data
let main_heap_ptr = memories[0].as_mut_ptr() as *mut VmCtxData; // let main_heap_ptr = memories[0].as_mut_ptr() as *mut VmCtxData;
unsafe { // unsafe {
main_heap_ptr.sub(1).write(data); // main_heap_ptr.sub(1).write(data);
&*(main_heap_ptr as *const VmCtx) // &*(main_heap_ptr as *const VmCtx)
} // }
} }
/// Returns a slice of the contents of allocated linear memory. /// Returns a slice of the contents of allocated linear memory.
@ -583,8 +570,8 @@ impl Clone for Instance {
} }
extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &VmCtx) -> i32 { extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &VmCtx) -> i32 {
// return 0; return 0;
unimplemented!(); // unimplemented!();
// let instance = &vmctx // let instance = &vmctx
// .data() // .data()
// .user_data // .user_data
@ -608,18 +595,24 @@ extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &VmCtx) -> i32 {
} }
extern "C" fn current_memory(memory_index: u32, vmctx: &VmCtx) -> u32 { extern "C" fn current_memory(memory_index: u32, vmctx: &VmCtx) -> u32 {
// return 0; let instance = &vmctx.user_data.instance;
println!("current_memory::init {:?}", memory_index);
let instance = &vmctx.data().user_data.instance;
let memory = &instance.memories[memory_index as usize]; let memory = &instance.memories[memory_index as usize];
println!(
"INSPECTED MEMORY ({:?}) {:?}",
memory.current_size(),
instance.inspect_memory(0, 0, 1)
);
memory.current_size() as u32 memory.current_size() as u32
// return 0;
// unimplemented!();
// println!("current_memory::init {:?}", memory_index);
// let instance = &vmctx.data().user_data.instance;
// let memory = &instance.memories[memory_index as usize];
// println!(
// "INSPECTED MEMORY ({:?}) {:?}",
// memory.current_size(),
// instance.inspect_memory(0, 0, 1)
// );
// memory.current_size() as u32
// return 1; // return 1;
// let vm = unsafe { // let vm = unsafe {
// (*vmctx) as *mut VmCtx // (*vmctx) as *mut VmCtx