From 4cfa031c5fa861c955b5f238b52fa44a9d4bfd06 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 5 Aug 2021 13:02:34 -0500 Subject: [PATCH] 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. --- cranelift/codegen/src/ir/immediates.rs | 6 ++++++ crates/wasmtime/src/externals.rs | 4 ++-- crates/wasmtime/src/trampoline/global.rs | 2 +- crates/wasmtime/src/values.rs | 6 ++++++ tests/all/globals.rs | 14 ++++++++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/cranelift/codegen/src/ir/immediates.rs b/cranelift/codegen/src/ir/immediates.rs index 9dd317d542..06c65277ba 100644 --- a/cranelift/codegen/src/ir/immediates.rs +++ b/cranelift/codegen/src/ir/immediates.rs @@ -360,6 +360,12 @@ impl From<&[u8]> for V128Imm { } } +impl From 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 diff --git a/crates/wasmtime/src/externals.rs b/crates/wasmtime/src/externals.rs index f8d4ef0462..3502ee4763 100644 --- a/crates/wasmtime/src/externals.rs +++ b/crates/wasmtime/src/externals.rs @@ -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(()) diff --git a/crates/wasmtime/src/trampoline/global.rs b/crates/wasmtime/src/trampoline/global.rs index 37eec1d9e0..20529de888 100644 --- a/crates/wasmtime/src/trampoline/global.rs +++ b/crates/wasmtime/src/trampoline/global.rs @@ -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), }, }; diff --git a/crates/wasmtime/src/values.rs b/crates/wasmtime/src/values.rs index c2d347d2e3..6b86e70ef1 100644 --- a/crates/wasmtime/src/values.rs +++ b/crates/wasmtime/src/values.rs @@ -270,6 +270,12 @@ impl From for Val { } } +impl From for Val { + fn from(val: u128) -> Val { + Val::V128(val) + } +} + pub(crate) fn into_checked_anyfunc( val: Val, store: &mut StoreOpaque, diff --git a/tests/all/globals.rs b/tests/all/globals.rs index 7561a38775..97ca1a6dbf 100644 --- a/tests/all/globals.rs +++ b/tests/all/globals.rs @@ -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(()) +}