Bump size of global up to 128 bits.

Fixes last spec test failure from the WAVM SIMD spec test.
This commit is contained in:
Nick Lewycky
2019-07-18 13:39:41 -07:00
parent 3be6a024aa
commit ea93b68165
5 changed files with 54 additions and 41 deletions

View File

@ -46,11 +46,11 @@ impl Global {
let local_global = vm::LocalGlobal { let local_global = vm::LocalGlobal {
data: match value { data: match value {
Value::I32(x) => x as u64, Value::I32(x) => x as u128,
Value::I64(x) => x as u64, Value::I64(x) => x as u128,
Value::F32(x) => x.to_bits() as u64, Value::F32(x) => x.to_bits() as u128,
Value::F64(x) => x.to_bits(), Value::F64(x) => x.to_bits() as u128,
Value::V128(_) => unimplemented!(), Value::V128(x) => x,
}, },
}; };
@ -76,11 +76,11 @@ impl Global {
if self.desc.ty == value.ty() { if self.desc.ty == value.ty() {
let local_global = vm::LocalGlobal { let local_global = vm::LocalGlobal {
data: match value { data: match value {
Value::I32(x) => x as u64, Value::I32(x) => x as u128,
Value::I64(x) => x as u64, Value::I64(x) => x as u128,
Value::F32(x) => x.to_bits() as u64, Value::F32(x) => x.to_bits() as u128,
Value::F64(x) => x.to_bits(), Value::F64(x) => x.to_bits() as u128,
Value::V128(_) => unimplemented!(), Value::V128(x) => x,
}, },
}; };
*self.storage.borrow_mut() = local_global; *self.storage.borrow_mut() = local_global;
@ -100,8 +100,8 @@ impl Global {
Type::I32 => Value::I32(data as i32), Type::I32 => Value::I32(data as i32),
Type::I64 => Value::I64(data as i64), Type::I64 => Value::I64(data as i64),
Type::F32 => Value::F32(f32::from_bits(data as u32)), Type::F32 => Value::F32(f32::from_bits(data as u32)),
Type::F64 => Value::F64(f64::from_bits(data)), Type::F64 => Value::F64(f64::from_bits(data as u64)),
Type::V128 => unimplemented!(), Type::V128 => Value::V128(data),
} }
} }

View File

@ -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)] #[cfg(unix)]
use libc::{mmap, mprotect, munmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_READ, PROT_WRITE}; use libc::{mmap, mprotect, munmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_READ, PROT_WRITE};
use std::{ use std::{
@ -62,34 +62,47 @@ pub struct LocalInstance {
impl Instance for LocalInstance { impl Instance for LocalInstance {
type Error = String; type Error = String;
fn call(&mut self, id: usize, args: &[Value]) -> Result<u64, Self::Error> { fn call(&mut self, id: usize, args: &[Value]) -> Result<u64, Self::Error> {
let mut args_u64: Vec<u64> = 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 offset = self.offsets[id];
let addr: *const u8 = unsafe { self.code.as_ptr().offset(offset as isize) }; let addr: *const u8 = unsafe { self.code.as_ptr().offset(offset as isize) };
use std::mem::transmute; use std::mem::transmute;
Ok(unsafe { Ok(unsafe {
match args.len() { match args_u64.len() {
0 => (transmute::<_, extern "C" fn() -> u64>(addr))(), 0 => (transmute::<_, extern "C" fn() -> u64>(addr))(),
1 => (transmute::<_, extern "C" fn(u64) -> u64>(addr))(args[0].to_u64()), 1 => (transmute::<_, extern "C" fn(u64) -> u64>(addr))(args_u64[0]),
2 => (transmute::<_, extern "C" fn(u64, u64) -> u64>(addr))( 2 => {
args[0].to_u64(), (transmute::<_, extern "C" fn(u64, u64) -> u64>(addr))(args_u64[0], args_u64[1])
args[1].to_u64(), }
),
3 => (transmute::<_, extern "C" fn(u64, u64, u64) -> u64>(addr))( 3 => (transmute::<_, extern "C" fn(u64, u64, u64) -> u64>(addr))(
args[0].to_u64(), args_u64[0],
args[1].to_u64(), args_u64[1],
args[2].to_u64(), args_u64[2],
), ),
4 => (transmute::<_, extern "C" fn(u64, u64, u64, u64) -> u64>(addr))( 4 => (transmute::<_, extern "C" fn(u64, u64, u64, u64) -> u64>(addr))(
args[0].to_u64(), args_u64[0],
args[1].to_u64(), args_u64[1],
args[2].to_u64(), args_u64[2],
args[3].to_u64(), args_u64[3],
), ),
5 => (transmute::<_, extern "C" fn(u64, u64, u64, u64, u64) -> u64>(addr))( 5 => (transmute::<_, extern "C" fn(u64, u64, u64, u64, u64) -> u64>(addr))(
args[0].to_u64(), args_u64[0],
args[1].to_u64(), args_u64[1],
args[2].to_u64(), args_u64[2],
args[3].to_u64(), args_u64[3],
args[4].to_u64(), args_u64[4],
), ),
_ => return Err("too many arguments".into()), _ => return Err("too many arguments".into()),
} }

View File

@ -95,7 +95,7 @@ pub struct ExecutionStateImage {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InstanceImage { pub struct InstanceImage {
pub memory: Option<Vec<u8>>, pub memory: Option<Vec<u8>>,
pub globals: Vec<u64>, pub globals: Vec<u128>,
pub execution_state: ExecutionStateImage, pub execution_state: ExecutionStateImage,
} }
@ -662,11 +662,11 @@ pub mod x64 {
// FIXME: Imported globals // FIXME: Imported globals
let globals_len = (*vmctx.module).info.globals.len(); let globals_len = (*vmctx.module).info.globals.len();
let globals: Vec<u64> = (0..globals_len) let globals: Vec<u128> = (0..globals_len)
.map(|i| { .map(|i| {
(*vmctx.local_backing).globals[LocalGlobalIndex::new(i)] (*vmctx.local_backing).globals[LocalGlobalIndex::new(i)]
.get() .get()
.to_u64() .to_u128()
}) })
.collect(); .collect();

View File

@ -51,13 +51,13 @@ impl Value {
} }
} }
pub fn to_u64(&self) -> u64 { pub fn to_u128(&self) -> u128 {
match *self { match *self {
Value::I32(x) => x as u32 as u64, Value::I32(x) => x as u128,
Value::I64(x) => x as u64, Value::I64(x) => x as u128,
Value::F32(x) => f32::to_bits(x) as u64, Value::F32(x) => f32::to_bits(x) as u128,
Value::F64(x) => f64::to_bits(x), Value::F64(x) => f64::to_bits(x) as u128,
Value::V128(_) => unimplemented!(), Value::V128(x) => x,
} }
} }
} }

View File

@ -535,7 +535,7 @@ impl LocalMemory {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
#[repr(C)] #[repr(C)]
pub struct LocalGlobal { pub struct LocalGlobal {
pub data: u64, pub data: u128,
} }
impl LocalGlobal { impl LocalGlobal {