diff --git a/lib/runtime-core/src/global.rs b/lib/runtime-core/src/global.rs index 16a75d6a7..8d4212531 100644 --- a/lib/runtime-core/src/global.rs +++ b/lib/runtime-core/src/global.rs @@ -46,11 +46,11 @@ impl Global { let local_global = vm::LocalGlobal { data: match value { - Value::I32(x) => x as u64, - Value::I64(x) => x as u64, - Value::F32(x) => x.to_bits() as u64, - Value::F64(x) => x.to_bits(), - Value::V128(_) => unimplemented!(), + Value::I32(x) => x as u128, + Value::I64(x) => x as u128, + Value::F32(x) => x.to_bits() as u128, + Value::F64(x) => x.to_bits() as u128, + Value::V128(x) => x, }, }; @@ -76,11 +76,11 @@ impl Global { if self.desc.ty == value.ty() { let local_global = vm::LocalGlobal { data: match value { - Value::I32(x) => x as u64, - Value::I64(x) => x as u64, - Value::F32(x) => x.to_bits() as u64, - Value::F64(x) => x.to_bits(), - Value::V128(_) => unimplemented!(), + Value::I32(x) => x as u128, + Value::I64(x) => x as u128, + Value::F32(x) => x.to_bits() as u128, + Value::F64(x) => x.to_bits() as u128, + Value::V128(x) => x, }, }; *self.storage.borrow_mut() = local_global; @@ -100,8 +100,8 @@ impl Global { Type::I32 => Value::I32(data as i32), Type::I64 => Value::I64(data as i64), Type::F32 => Value::F32(f32::from_bits(data as u32)), - Type::F64 => Value::F64(f64::from_bits(data)), - Type::V128 => unimplemented!(), + Type::F64 => Value::F64(f64::from_bits(data as u64)), + Type::V128 => Value::V128(data), } } diff --git a/lib/runtime-core/src/loader.rs b/lib/runtime-core/src/loader.rs index 5ef127ec7..b02e9e859 100644 --- a/lib/runtime-core/src/loader.rs +++ b/lib/runtime-core/src/loader.rs @@ -1,4 +1,4 @@ -use crate::{backend::RunnableModule, module::ModuleInfo, types::Value, vm::Ctx}; +use crate::{backend::RunnableModule, module::ModuleInfo, types::Type, types::Value, vm::Ctx}; #[cfg(unix)] use libc::{mmap, mprotect, munmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_READ, PROT_WRITE}; use std::{ @@ -62,34 +62,47 @@ pub struct LocalInstance { impl Instance for LocalInstance { type Error = String; fn call(&mut self, id: usize, args: &[Value]) -> Result { + let mut args_u64: Vec = Vec::new(); + for arg in args { + if arg.ty() == Type::V128 { + let bytes = arg.to_u128().to_le_bytes(); + let mut lo = [0u8; 8]; + lo.clone_from_slice(&bytes[0..8]); + args_u64.push(u64::from_le_bytes(lo)); + let mut hi = [0u8; 8]; + hi.clone_from_slice(&bytes[8..16]); + args_u64.push(u64::from_le_bytes(hi)); + } else { + args_u64.push(arg.to_u128() as u64); + } + } let offset = self.offsets[id]; let addr: *const u8 = unsafe { self.code.as_ptr().offset(offset as isize) }; use std::mem::transmute; Ok(unsafe { - match args.len() { + match args_u64.len() { 0 => (transmute::<_, extern "C" fn() -> u64>(addr))(), - 1 => (transmute::<_, extern "C" fn(u64) -> u64>(addr))(args[0].to_u64()), - 2 => (transmute::<_, extern "C" fn(u64, u64) -> u64>(addr))( - args[0].to_u64(), - args[1].to_u64(), - ), + 1 => (transmute::<_, extern "C" fn(u64) -> u64>(addr))(args_u64[0]), + 2 => { + (transmute::<_, extern "C" fn(u64, u64) -> u64>(addr))(args_u64[0], args_u64[1]) + } 3 => (transmute::<_, extern "C" fn(u64, u64, u64) -> u64>(addr))( - args[0].to_u64(), - args[1].to_u64(), - args[2].to_u64(), + args_u64[0], + args_u64[1], + args_u64[2], ), 4 => (transmute::<_, extern "C" fn(u64, u64, u64, u64) -> u64>(addr))( - args[0].to_u64(), - args[1].to_u64(), - args[2].to_u64(), - args[3].to_u64(), + args_u64[0], + args_u64[1], + args_u64[2], + args_u64[3], ), 5 => (transmute::<_, extern "C" fn(u64, u64, u64, u64, u64) -> u64>(addr))( - args[0].to_u64(), - args[1].to_u64(), - args[2].to_u64(), - args[3].to_u64(), - args[4].to_u64(), + args_u64[0], + args_u64[1], + args_u64[2], + args_u64[3], + args_u64[4], ), _ => return Err("too many arguments".into()), } diff --git a/lib/runtime-core/src/state.rs b/lib/runtime-core/src/state.rs index 8650cb4ac..6fd47b204 100644 --- a/lib/runtime-core/src/state.rs +++ b/lib/runtime-core/src/state.rs @@ -95,7 +95,7 @@ pub struct ExecutionStateImage { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct InstanceImage { pub memory: Option>, - pub globals: Vec, + pub globals: Vec, pub execution_state: ExecutionStateImage, } @@ -662,11 +662,11 @@ pub mod x64 { // FIXME: Imported globals let globals_len = (*vmctx.module).info.globals.len(); - let globals: Vec = (0..globals_len) + let globals: Vec = (0..globals_len) .map(|i| { (*vmctx.local_backing).globals[LocalGlobalIndex::new(i)] .get() - .to_u64() + .to_u128() }) .collect(); diff --git a/lib/runtime-core/src/types.rs b/lib/runtime-core/src/types.rs index ac3df0343..ad00a1588 100644 --- a/lib/runtime-core/src/types.rs +++ b/lib/runtime-core/src/types.rs @@ -51,13 +51,13 @@ impl Value { } } - pub fn to_u64(&self) -> u64 { + pub fn to_u128(&self) -> u128 { match *self { - Value::I32(x) => x as u32 as u64, - Value::I64(x) => x as u64, - Value::F32(x) => f32::to_bits(x) as u64, - Value::F64(x) => f64::to_bits(x), - Value::V128(_) => unimplemented!(), + Value::I32(x) => x as u128, + Value::I64(x) => x as u128, + Value::F32(x) => f32::to_bits(x) as u128, + Value::F64(x) => f64::to_bits(x) as u128, + Value::V128(x) => x, } } } diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 1e0b3773d..1a7ed37de 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -535,7 +535,7 @@ impl LocalMemory { #[derive(Debug, Clone, Copy)] #[repr(C)] pub struct LocalGlobal { - pub data: u64, + pub data: u128, } impl LocalGlobal {