Browse Source
Implement API support for v128-globals (#3147)
Found via fuzzing, and looks like these were accidentally left out along
the way SIMD was taking shape.
pull/3150/head
Alex Crichton
3 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with
29 additions and
3 deletions
-
cranelift/codegen/src/ir/immediates.rs
-
crates/wasmtime/src/externals.rs
-
crates/wasmtime/src/trampoline/global.rs
-
crates/wasmtime/src/values.rs
-
tests/all/globals.rs
|
|
@ -360,6 +360,12 @@ impl From<&[u8]> for V128Imm { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl From<u128> for V128Imm { |
|
|
|
fn from(val: u128) -> Self { |
|
|
|
V128Imm(val.to_le_bytes()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// 32-bit signed immediate offset.
|
|
|
|
///
|
|
|
|
/// This is used to encode an immediate offset for load/store instructions. All supported ISAs have
|
|
|
|
|
|
@ -309,7 +309,7 @@ impl Global { |
|
|
|
ValType::FuncRef => { |
|
|
|
from_checked_anyfunc(definition.as_anyfunc() as *mut _, &mut store.opaque()) |
|
|
|
} |
|
|
|
ty => unimplemented!("Global::get for {:?}", ty), |
|
|
|
ValType::V128 => Val::V128(*definition.as_u128()), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -355,7 +355,7 @@ impl Global { |
|
|
|
let old = mem::replace(definition.as_externref_mut(), x.map(|x| x.inner)); |
|
|
|
drop(old); |
|
|
|
} |
|
|
|
_ => unimplemented!("Global::set for {:?}", val.ty()), |
|
|
|
Val::V128(i) => *definition.as_u128_mut() = i, |
|
|
|
} |
|
|
|
} |
|
|
|
Ok(()) |
|
|
|
|
|
@ -27,6 +27,7 @@ pub fn create_global(store: &mut StoreOpaque<'_>, gt: &GlobalType, val: Val) -> |
|
|
|
Val::I64(i) => wasm::GlobalInit::I64Const(i), |
|
|
|
Val::F32(f) => wasm::GlobalInit::F32Const(f), |
|
|
|
Val::F64(f) => wasm::GlobalInit::F64Const(f), |
|
|
|
Val::V128(i) => wasm::GlobalInit::V128Const(i.into()), |
|
|
|
Val::ExternRef(None) | Val::FuncRef(None) => wasm::GlobalInit::RefNullConst, |
|
|
|
Val::ExternRef(Some(x)) => { |
|
|
|
// There is no `GlobalInit` variant for using an existing
|
|
|
@ -61,7 +62,6 @@ pub fn create_global(store: &mut StoreOpaque<'_>, gt: &GlobalType, val: Val) -> |
|
|
|
|
|
|
|
wasm::GlobalInit::RefFunc(func_index) |
|
|
|
} |
|
|
|
_ => unimplemented!("create_global for {:?}", gt), |
|
|
|
}, |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
@ -270,6 +270,12 @@ impl From<Func> for Val { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl From<u128> for Val { |
|
|
|
fn from(val: u128) -> Val { |
|
|
|
Val::V128(val) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pub(crate) fn into_checked_anyfunc( |
|
|
|
val: Val, |
|
|
|
store: &mut StoreOpaque, |
|
|
|
|
|
@ -89,3 +89,17 @@ fn use_after_drop() -> anyhow::Result<()> { |
|
|
|
assert_eq!(g.get(&mut store).i32(), Some(101)); |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn v128() -> anyhow::Result<()> { |
|
|
|
let mut store = Store::<()>::default(); |
|
|
|
let g = Global::new( |
|
|
|
&mut store, |
|
|
|
GlobalType::new(ValType::V128, Mutability::Var), |
|
|
|
0u128.into(), |
|
|
|
)?; |
|
|
|
assert_eq!(g.get(&mut store).v128(), Some(0)); |
|
|
|
g.set(&mut store, 1u128.into())?; |
|
|
|
assert_eq!(g.get(&mut store).v128(), Some(1)); |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|