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.
This commit is contained in:
@@ -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.
|
/// 32-bit signed immediate offset.
|
||||||
///
|
///
|
||||||
/// This is used to encode an immediate offset for load/store instructions. All supported ISAs have
|
/// This is used to encode an immediate offset for load/store instructions. All supported ISAs have
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ impl Global {
|
|||||||
ValType::FuncRef => {
|
ValType::FuncRef => {
|
||||||
from_checked_anyfunc(definition.as_anyfunc() as *mut _, &mut store.opaque())
|
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));
|
let old = mem::replace(definition.as_externref_mut(), x.map(|x| x.inner));
|
||||||
drop(old);
|
drop(old);
|
||||||
}
|
}
|
||||||
_ => unimplemented!("Global::set for {:?}", val.ty()),
|
Val::V128(i) => *definition.as_u128_mut() = i,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ pub fn create_global(store: &mut StoreOpaque<'_>, gt: &GlobalType, val: Val) ->
|
|||||||
Val::I64(i) => wasm::GlobalInit::I64Const(i),
|
Val::I64(i) => wasm::GlobalInit::I64Const(i),
|
||||||
Val::F32(f) => wasm::GlobalInit::F32Const(f),
|
Val::F32(f) => wasm::GlobalInit::F32Const(f),
|
||||||
Val::F64(f) => wasm::GlobalInit::F64Const(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(None) | Val::FuncRef(None) => wasm::GlobalInit::RefNullConst,
|
||||||
Val::ExternRef(Some(x)) => {
|
Val::ExternRef(Some(x)) => {
|
||||||
// There is no `GlobalInit` variant for using an existing
|
// 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)
|
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(
|
pub(crate) fn into_checked_anyfunc(
|
||||||
val: Val,
|
val: Val,
|
||||||
store: &mut StoreOpaque,
|
store: &mut StoreOpaque,
|
||||||
|
|||||||
@@ -89,3 +89,17 @@ fn use_after_drop() -> anyhow::Result<()> {
|
|||||||
assert_eq!(g.get(&mut store).i32(), Some(101));
|
assert_eq!(g.get(&mut store).i32(), Some(101));
|
||||||
Ok(())
|
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(())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user