wiggle: adapt Wiggle guest slices for unsafe shared use (#5229)
* wiggle: adapt Wiggle guest slices for `unsafe` shared use When multiple threads can concurrently modify a WebAssembly shared memory, the underlying data for a Wiggle `GuestSlice` and `GuestSliceMut` could change due to access from other threads. This breaks Rust guarantees when `&[T]` and `&mut [T]` slices are handed out. This change modifies `GuestPtr` to make `as_slice` and `as_slice_mut` return an `Option` which is `None` when the underlying WebAssembly memory is shared. But WASI implementations still need access to the underlying WebAssembly memory, both to read to it and write from it. This change adds new APIs: - `GuestPtr::to_vec` copies the bytes from WebAssembly memory (from which we can safely take a `&[T]`) - `GuestPtr::as_unsafe_slice_mut` returns a wrapper `struct` from which we can `unsafe`-ly return a mutable slice (users must accept the unsafety of concurrently modifying a `&mut [T]`) This approach allows us to maintain Wiggle's borrow-checking infrastructure, which enforces the guarantee that Wiggle will not modify overlapping regions, e.g. This is important because the underlying system calls may expect this. Though other threads may modify the same underlying region, this is impossible to prevent; at least Wiggle will not be able to do so. Finally, the changes to Wiggle's API are propagated to all WASI implementations in Wasmtime. For now, code locations that attempt to get a guest slice will panic if the underlying memory is shared. Note that Wiggle is not enabled for shared memory (that will come later in something like #5054), but when it is, these panics will be clear indicators of locations that must be re-implemented in a thread-safe way. * review: remove double cast * review: refactor to include more logic in 'UnsafeGuestSlice' * review: add reference to #4203 * review: link all thread-safe WASI fixups to #5235 * fix: consume 'UnsafeGuestSlice' during conversion to safe versions * review: remove 'as_slice' and 'as_slice_mut' * review: use 'as_unsafe_slice_mut' in 'to_vec' * review: add `UnsafeBorrowResult`
This commit is contained in:
@@ -468,14 +468,16 @@ impl wasi_unstable::WasiUnstable for WasiCtx {
|
|||||||
.get_file_mut(u32::from(fd))?
|
.get_file_mut(u32::from(fd))?
|
||||||
.get_cap_mut(FileCaps::READ)?;
|
.get_cap_mut(FileCaps::READ)?;
|
||||||
|
|
||||||
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> = iovs
|
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> =
|
||||||
.iter()
|
iovs.iter()
|
||||||
.map(|iov_ptr| {
|
.map(|iov_ptr| {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Iovec = iov_ptr.read()?;
|
let iov: types::Iovec = iov_ptr.read()?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?)
|
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?.expect(
|
||||||
})
|
"cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)",
|
||||||
.collect::<Result<_, Error>>()?;
|
))
|
||||||
|
})
|
||||||
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@@ -497,14 +499,16 @@ impl wasi_unstable::WasiUnstable for WasiCtx {
|
|||||||
.get_file_mut(u32::from(fd))?
|
.get_file_mut(u32::from(fd))?
|
||||||
.get_cap_mut(FileCaps::READ | FileCaps::SEEK)?;
|
.get_cap_mut(FileCaps::READ | FileCaps::SEEK)?;
|
||||||
|
|
||||||
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> = iovs
|
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> =
|
||||||
.iter()
|
iovs.iter()
|
||||||
.map(|iov_ptr| {
|
.map(|iov_ptr| {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Iovec = iov_ptr.read()?;
|
let iov: types::Iovec = iov_ptr.read()?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?)
|
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?.expect(
|
||||||
})
|
"cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)",
|
||||||
.collect::<Result<_, Error>>()?;
|
))
|
||||||
|
})
|
||||||
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@@ -530,7 +534,11 @@ impl wasi_unstable::WasiUnstable for WasiCtx {
|
|||||||
.map(|iov_ptr| {
|
.map(|iov_ptr| {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Ciovec = iov_ptr.read()?;
|
let iov: types::Ciovec = iov_ptr.read()?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice()?)
|
Ok(iov
|
||||||
|
.buf
|
||||||
|
.as_array(iov.buf_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)"))
|
||||||
})
|
})
|
||||||
.collect::<Result<_, Error>>()?;
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
@@ -559,7 +567,11 @@ impl wasi_unstable::WasiUnstable for WasiCtx {
|
|||||||
.map(|iov_ptr| {
|
.map(|iov_ptr| {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Ciovec = iov_ptr.read()?;
|
let iov: types::Ciovec = iov_ptr.read()?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice()?)
|
Ok(iov
|
||||||
|
.buf
|
||||||
|
.as_array(iov.buf_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)"))
|
||||||
})
|
})
|
||||||
.collect::<Result<_, Error>>()?;
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
|
|||||||
@@ -521,14 +521,16 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
.get_file_mut(u32::from(fd))?
|
.get_file_mut(u32::from(fd))?
|
||||||
.get_cap_mut(FileCaps::READ)?;
|
.get_cap_mut(FileCaps::READ)?;
|
||||||
|
|
||||||
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> = iovs
|
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> =
|
||||||
.iter()
|
iovs.iter()
|
||||||
.map(|iov_ptr| {
|
.map(|iov_ptr| {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Iovec = iov_ptr.read()?;
|
let iov: types::Iovec = iov_ptr.read()?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?)
|
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?.expect(
|
||||||
})
|
"cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)",
|
||||||
.collect::<Result<_, Error>>()?;
|
))
|
||||||
|
})
|
||||||
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@@ -550,14 +552,16 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
.get_file_mut(u32::from(fd))?
|
.get_file_mut(u32::from(fd))?
|
||||||
.get_cap_mut(FileCaps::READ | FileCaps::SEEK)?;
|
.get_cap_mut(FileCaps::READ | FileCaps::SEEK)?;
|
||||||
|
|
||||||
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> = iovs
|
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> =
|
||||||
.iter()
|
iovs.iter()
|
||||||
.map(|iov_ptr| {
|
.map(|iov_ptr| {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Iovec = iov_ptr.read()?;
|
let iov: types::Iovec = iov_ptr.read()?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?)
|
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?.expect(
|
||||||
})
|
"cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)",
|
||||||
.collect::<Result<_, Error>>()?;
|
))
|
||||||
|
})
|
||||||
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@@ -583,7 +587,11 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
.map(|iov_ptr| {
|
.map(|iov_ptr| {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Ciovec = iov_ptr.read()?;
|
let iov: types::Ciovec = iov_ptr.read()?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice()?)
|
Ok(iov
|
||||||
|
.buf
|
||||||
|
.as_array(iov.buf_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)"))
|
||||||
})
|
})
|
||||||
.collect::<Result<_, Error>>()?;
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
@@ -612,7 +620,11 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
.map(|iov_ptr| {
|
.map(|iov_ptr| {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Ciovec = iov_ptr.read()?;
|
let iov: types::Ciovec = iov_ptr.read()?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice()?)
|
Ok(iov
|
||||||
|
.buf
|
||||||
|
.as_array(iov.buf_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)"))
|
||||||
})
|
})
|
||||||
.collect::<Result<_, Error>>()?;
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
@@ -654,7 +666,10 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
if path_len < path_max_len as usize {
|
if path_len < path_max_len as usize {
|
||||||
return Err(Error::name_too_long());
|
return Err(Error::name_too_long());
|
||||||
}
|
}
|
||||||
let mut p_memory = path.as_array(path_len as u32).as_slice_mut()?;
|
let mut p_memory = path
|
||||||
|
.as_array(path_len as u32)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
p_memory.copy_from_slice(path_bytes);
|
p_memory.copy_from_slice(path_bytes);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@@ -948,7 +963,10 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
if link_len > buf_len as usize {
|
if link_len > buf_len as usize {
|
||||||
return Err(Error::range());
|
return Err(Error::range());
|
||||||
}
|
}
|
||||||
let mut buf = buf.as_array(link_len as u32).as_slice_mut()?;
|
let mut buf = buf
|
||||||
|
.as_array(link_len as u32)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
buf.copy_from_slice(link_bytes);
|
buf.copy_from_slice(link_bytes);
|
||||||
Ok(link_len as types::Size)
|
Ok(link_len as types::Size)
|
||||||
}
|
}
|
||||||
@@ -1236,7 +1254,10 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
buf: &GuestPtr<'a, u8>,
|
buf: &GuestPtr<'a, u8>,
|
||||||
buf_len: types::Size,
|
buf_len: types::Size,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut buf = buf.as_array(buf_len).as_slice_mut()?;
|
let mut buf = buf
|
||||||
|
.as_array(buf_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
self.random.try_fill_bytes(buf.deref_mut())?;
|
self.random.try_fill_bytes(buf.deref_mut())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1273,14 +1294,17 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
.get_file_mut(u32::from(fd))?
|
.get_file_mut(u32::from(fd))?
|
||||||
.get_cap_mut(FileCaps::READ)?;
|
.get_cap_mut(FileCaps::READ)?;
|
||||||
|
|
||||||
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> = ri_data
|
let mut guest_slices: Vec<wiggle::GuestSliceMut<u8>> =
|
||||||
.iter()
|
ri_data
|
||||||
.map(|iov_ptr| {
|
.iter()
|
||||||
let iov_ptr = iov_ptr?;
|
.map(|iov_ptr| {
|
||||||
let iov: types::Iovec = iov_ptr.read()?;
|
let iov_ptr = iov_ptr?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?)
|
let iov: types::Iovec = iov_ptr.read()?;
|
||||||
})
|
Ok(iov.buf.as_array(iov.buf_len).as_slice_mut()?.expect(
|
||||||
.collect::<Result<_, Error>>()?;
|
"cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)",
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
let mut ioslices: Vec<IoSliceMut> = guest_slices
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@@ -1307,7 +1331,11 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
.map(|iov_ptr| {
|
.map(|iov_ptr| {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Ciovec = iov_ptr.read()?;
|
let iov: types::Ciovec = iov_ptr.read()?;
|
||||||
Ok(iov.buf.as_array(iov.buf_len).as_slice()?)
|
Ok(iov
|
||||||
|
.buf
|
||||||
|
.as_array(iov.buf_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)"))
|
||||||
})
|
})
|
||||||
.collect::<Result<_, Error>>()?;
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,10 @@ impl super::wasi_ephemeral_crypto_asymmetric_common::WasiEphemeralCryptoAsymmetr
|
|||||||
kp_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
kp_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
kp_id_max_len: guest_types::Size,
|
kp_id_max_len: guest_types::Size,
|
||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let key_id_buf = &mut *kp_id_ptr.as_array(kp_id_max_len).as_slice_mut()?;
|
let key_id_buf = &mut *kp_id_ptr
|
||||||
|
.as_array(kp_id_max_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self).keypair_store_managed(
|
Ok((&*self).keypair_store_managed(
|
||||||
secrets_manager_handle.into(),
|
secrets_manager_handle.into(),
|
||||||
kp_handle.into(),
|
kp_handle.into(),
|
||||||
@@ -69,7 +72,10 @@ impl super::wasi_ephemeral_crypto_asymmetric_common::WasiEphemeralCryptoAsymmetr
|
|||||||
kp_id_len: guest_types::Size,
|
kp_id_len: guest_types::Size,
|
||||||
kp_version: guest_types::Version,
|
kp_version: guest_types::Version,
|
||||||
) -> Result<guest_types::Keypair, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Keypair, guest_types::CryptoErrno> {
|
||||||
let kp_id = &*kp_id_ptr.as_array(kp_id_len).as_slice()?;
|
let kp_id = &*kp_id_ptr
|
||||||
|
.as_array(kp_id_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.keypair_from_id(secrets_manager_handle.into(), kp_id, Version(kp_version))?
|
.keypair_from_id(secrets_manager_handle.into(), kp_id, Version(kp_version))?
|
||||||
.into())
|
.into())
|
||||||
@@ -102,7 +108,10 @@ impl super::wasi_ephemeral_crypto_asymmetric_common::WasiEphemeralCryptoAsymmetr
|
|||||||
encoding: guest_types::KeypairEncoding,
|
encoding: guest_types::KeypairEncoding,
|
||||||
) -> Result<guest_types::Keypair, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Keypair, guest_types::CryptoErrno> {
|
||||||
let alg_str = &*alg_str.as_str()?;
|
let alg_str = &*alg_str.as_str()?;
|
||||||
let encoded = &*encoded_ptr.as_array(encoded_len).as_slice()?;
|
let encoded = &*encoded_ptr
|
||||||
|
.as_array(encoded_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.keypair_import(alg_type.into(), alg_str, encoded, encoding.into())?
|
.keypair_import(alg_type.into(), alg_str, encoded, encoding.into())?
|
||||||
.into())
|
.into())
|
||||||
@@ -114,7 +123,10 @@ impl super::wasi_ephemeral_crypto_asymmetric_common::WasiEphemeralCryptoAsymmetr
|
|||||||
kp_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
kp_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
kp_id_max_len: guest_types::Size,
|
kp_id_max_len: guest_types::Size,
|
||||||
) -> Result<(guest_types::Size, guest_types::Version), guest_types::CryptoErrno> {
|
) -> Result<(guest_types::Size, guest_types::Version), guest_types::CryptoErrno> {
|
||||||
let kp_id_buf = &mut *kp_id_ptr.as_array(kp_id_max_len as _).as_slice_mut()?;
|
let kp_id_buf = &mut *kp_id_ptr
|
||||||
|
.as_array(kp_id_max_len as _)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
let (kp_id, version) = (&*self).keypair_id(kp_handle.into())?;
|
let (kp_id, version) = (&*self).keypair_id(kp_handle.into())?;
|
||||||
ensure!(kp_id.len() <= kp_id_buf.len(), CryptoError::Overflow.into());
|
ensure!(kp_id.len() <= kp_id_buf.len(), CryptoError::Overflow.into());
|
||||||
kp_id_buf.copy_from_slice(&kp_id);
|
kp_id_buf.copy_from_slice(&kp_id);
|
||||||
@@ -156,7 +168,10 @@ impl super::wasi_ephemeral_crypto_asymmetric_common::WasiEphemeralCryptoAsymmetr
|
|||||||
encoding: guest_types::PublickeyEncoding,
|
encoding: guest_types::PublickeyEncoding,
|
||||||
) -> Result<guest_types::Publickey, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Publickey, guest_types::CryptoErrno> {
|
||||||
let alg_str = &*alg_str.as_str()?;
|
let alg_str = &*alg_str.as_str()?;
|
||||||
let encoded = &*encoded_ptr.as_array(encoded_len).as_slice()?;
|
let encoded = &*encoded_ptr
|
||||||
|
.as_array(encoded_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.publickey_import(alg_type.into(), alg_str, encoded, encoding.into())?
|
.publickey_import(alg_type.into(), alg_str, encoded, encoding.into())?
|
||||||
.into())
|
.into())
|
||||||
@@ -204,7 +219,10 @@ impl super::wasi_ephemeral_crypto_asymmetric_common::WasiEphemeralCryptoAsymmetr
|
|||||||
encoding: guest_types::SecretkeyEncoding,
|
encoding: guest_types::SecretkeyEncoding,
|
||||||
) -> Result<guest_types::Secretkey, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Secretkey, guest_types::CryptoErrno> {
|
||||||
let alg_str = &*alg_str.as_str()?;
|
let alg_str = &*alg_str.as_str()?;
|
||||||
let encoded = &*encoded_ptr.as_array(encoded_len).as_slice()?;
|
let encoded = &*encoded_ptr
|
||||||
|
.as_array(encoded_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.secretkey_import(alg_type.into(), alg_str, encoded, encoding.into())?
|
.secretkey_import(alg_type.into(), alg_str, encoded, encoding.into())?
|
||||||
.into())
|
.into())
|
||||||
|
|||||||
@@ -28,7 +28,12 @@ impl super::wasi_ephemeral_crypto_common::WasiEphemeralCryptoCommon for WasiCryp
|
|||||||
value_len: guest_types::Size,
|
value_len: guest_types::Size,
|
||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let name_str: &str = &*name_str.as_str()?;
|
let name_str: &str = &*name_str.as_str()?;
|
||||||
let value: &[u8] = { &*value_ptr.as_array(value_len).as_slice()? };
|
let value: &[u8] = {
|
||||||
|
&*value_ptr
|
||||||
|
.as_array(value_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)")
|
||||||
|
};
|
||||||
Ok((&*self).options_set(options_handle.into(), name_str, value)?)
|
Ok((&*self).options_set(options_handle.into(), name_str, value)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,8 +45,14 @@ impl super::wasi_ephemeral_crypto_common::WasiEphemeralCryptoCommon for WasiCryp
|
|||||||
buffer_len: guest_types::Size,
|
buffer_len: guest_types::Size,
|
||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let name_str: &str = &*name_str.as_str()?;
|
let name_str: &str = &*name_str.as_str()?;
|
||||||
let buffer: &'static mut [u8] =
|
let buffer: &'static mut [u8] = unsafe {
|
||||||
unsafe { std::mem::transmute(&mut *buffer_ptr.as_array(buffer_len).as_slice_mut()?) };
|
std::mem::transmute(
|
||||||
|
&mut *buffer_ptr
|
||||||
|
.as_array(buffer_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)"),
|
||||||
|
)
|
||||||
|
};
|
||||||
Ok((&*self).options_set_guest_buffer(options_handle.into(), name_str, buffer)?)
|
Ok((&*self).options_set_guest_buffer(options_handle.into(), name_str, buffer)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +83,12 @@ impl super::wasi_ephemeral_crypto_common::WasiEphemeralCryptoCommon for WasiCryp
|
|||||||
buf_ptr: &wiggle::GuestPtr<'_, u8>,
|
buf_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
buf_len: guest_types::Size,
|
buf_len: guest_types::Size,
|
||||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||||
let buf: &mut [u8] = { &mut *buf_ptr.as_array(buf_len).as_slice_mut()? };
|
let buf: &mut [u8] = {
|
||||||
|
&mut *buf_ptr
|
||||||
|
.as_array(buf_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)")
|
||||||
|
};
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.array_output_pull(array_output_handle.into(), buf)?
|
.array_output_pull(array_output_handle.into(), buf)?
|
||||||
.try_into()?)
|
.try_into()?)
|
||||||
@@ -107,7 +123,12 @@ impl super::wasi_ephemeral_crypto_common::WasiEphemeralCryptoCommon for WasiCryp
|
|||||||
key_id_len: guest_types::Size,
|
key_id_len: guest_types::Size,
|
||||||
key_version: guest_types::Version,
|
key_version: guest_types::Version,
|
||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let key_id: &[u8] = { &*key_id_ptr.as_array(key_id_len).as_slice()? };
|
let key_id: &[u8] = {
|
||||||
|
&*key_id_ptr
|
||||||
|
.as_array(key_id_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)")
|
||||||
|
};
|
||||||
Ok((&*self).secrets_manager_invalidate(
|
Ok((&*self).secrets_manager_invalidate(
|
||||||
secrets_manager_handle.into(),
|
secrets_manager_handle.into(),
|
||||||
key_id,
|
key_id,
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ impl super::wasi_ephemeral_crypto_kx::WasiEphemeralCryptoKx for WasiCryptoCtx {
|
|||||||
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
||||||
let encapsulated_secret = &*encapsulated_secret_ptr
|
let encapsulated_secret = &*encapsulated_secret_ptr
|
||||||
.as_array(encapsulated_secret_len)
|
.as_array(encapsulated_secret_len)
|
||||||
.as_slice()?;
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.kx_decapsulate(sk_handle.into(), encapsulated_secret)?
|
.kx_decapsulate(sk_handle.into(), encapsulated_secret)?
|
||||||
.into())
|
.into())
|
||||||
|
|||||||
@@ -23,7 +23,10 @@ impl super::wasi_ephemeral_crypto_signatures::WasiEphemeralCryptoSignatures for
|
|||||||
encoding: guest_types::SignatureEncoding,
|
encoding: guest_types::SignatureEncoding,
|
||||||
) -> Result<guest_types::Signature, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Signature, guest_types::CryptoErrno> {
|
||||||
let alg_str = &*alg_str.as_str()?;
|
let alg_str = &*alg_str.as_str()?;
|
||||||
let encoded = &*encoded_ptr.as_array(encoded_len).as_slice()?;
|
let encoded = &*encoded_ptr
|
||||||
|
.as_array(encoded_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.signature_import(alg_str, encoded, encoding.into())?
|
.signature_import(alg_str, encoded, encoding.into())?
|
||||||
.into())
|
.into())
|
||||||
@@ -42,7 +45,10 @@ impl super::wasi_ephemeral_crypto_signatures::WasiEphemeralCryptoSignatures for
|
|||||||
input_ptr: &wiggle::GuestPtr<'_, u8>,
|
input_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
input_len: guest_types::Size,
|
input_len: guest_types::Size,
|
||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let input = &*input_ptr.as_array(input_len).as_slice()?;
|
let input = &*input_ptr
|
||||||
|
.as_array(input_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self).signature_state_update(state_handle.into(), input)?)
|
Ok((&*self).signature_state_update(state_handle.into(), input)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +83,10 @@ impl super::wasi_ephemeral_crypto_signatures::WasiEphemeralCryptoSignatures for
|
|||||||
input_ptr: &wiggle::GuestPtr<'_, u8>,
|
input_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
input_len: guest_types::Size,
|
input_len: guest_types::Size,
|
||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let input: &[u8] = &*input_ptr.as_array(input_len).as_slice()?;
|
let input: &[u8] = &*input_ptr
|
||||||
|
.as_array(input_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok(
|
Ok(
|
||||||
(&*self)
|
(&*self)
|
||||||
.signature_verification_state_update(verification_state_handle.into(), input)?,
|
.signature_verification_state_update(verification_state_handle.into(), input)?,
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let key_id_buf = &mut *symmetric_key_id_ptr
|
let key_id_buf = &mut *symmetric_key_id_ptr
|
||||||
.as_array(symmetric_key_id_max_len)
|
.as_array(symmetric_key_id_max_len)
|
||||||
.as_slice_mut()?;
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self).symmetric_key_store_managed(
|
Ok((&*self).symmetric_key_store_managed(
|
||||||
secrets_manager_handle.into(),
|
secrets_manager_handle.into(),
|
||||||
symmetric_key_handle.into(),
|
symmetric_key_handle.into(),
|
||||||
@@ -67,7 +68,8 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
) -> Result<guest_types::SymmetricKey, guest_types::CryptoErrno> {
|
) -> Result<guest_types::SymmetricKey, guest_types::CryptoErrno> {
|
||||||
let symmetric_key_id = &*symmetric_key_id_ptr
|
let symmetric_key_id = &*symmetric_key_id_ptr
|
||||||
.as_array(symmetric_key_id_len)
|
.as_array(symmetric_key_id_len)
|
||||||
.as_slice()?;
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.symmetric_key_from_id(
|
.symmetric_key_from_id(
|
||||||
secrets_manager_handle.into(),
|
secrets_manager_handle.into(),
|
||||||
@@ -101,7 +103,10 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
raw_len: guest_types::Size,
|
raw_len: guest_types::Size,
|
||||||
) -> Result<guest_types::SymmetricKey, guest_types::CryptoErrno> {
|
) -> Result<guest_types::SymmetricKey, guest_types::CryptoErrno> {
|
||||||
let alg_str = &*alg_str.as_str()?;
|
let alg_str = &*alg_str.as_str()?;
|
||||||
let raw = &*raw_ptr.as_array(raw_len).as_slice()?;
|
let raw = &*raw_ptr
|
||||||
|
.as_array(raw_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self).symmetric_key_import(alg_str, raw)?.into())
|
Ok((&*self).symmetric_key_import(alg_str, raw)?.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +127,8 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
) -> Result<(guest_types::Size, guest_types::Version), guest_types::CryptoErrno> {
|
) -> Result<(guest_types::Size, guest_types::Version), guest_types::CryptoErrno> {
|
||||||
let key_id_buf = &mut *symmetric_key_id_ptr
|
let key_id_buf = &mut *symmetric_key_id_ptr
|
||||||
.as_array(symmetric_key_id_max_len)
|
.as_array(symmetric_key_id_max_len)
|
||||||
.as_slice_mut()?;
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
let (key_id, version) = (&*self).symmetric_key_id(symmetric_key_handle.into())?;
|
let (key_id, version) = (&*self).symmetric_key_id(symmetric_key_handle.into())?;
|
||||||
ensure!(
|
ensure!(
|
||||||
key_id.len() <= key_id_buf.len(),
|
key_id.len() <= key_id_buf.len(),
|
||||||
@@ -173,7 +179,10 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
value_max_len: guest_types::Size,
|
value_max_len: guest_types::Size,
|
||||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||||
let name_str: &str = &*name_str.as_str()?;
|
let name_str: &str = &*name_str.as_str()?;
|
||||||
let value = &mut *value_ptr.as_array(value_max_len).as_slice_mut()?;
|
let value = &mut *value_ptr
|
||||||
|
.as_array(value_max_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.options_get(symmetric_state_handle.into(), name_str, value)?
|
.options_get(symmetric_state_handle.into(), name_str, value)?
|
||||||
.try_into()?)
|
.try_into()?)
|
||||||
@@ -201,7 +210,10 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
data_len: guest_types::Size,
|
data_len: guest_types::Size,
|
||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
let data = &*data_ptr
|
||||||
|
.as_array(data_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self).symmetric_state_absorb(symmetric_state_handle.into(), data)?)
|
Ok((&*self).symmetric_state_absorb(symmetric_state_handle.into(), data)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +223,10 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
out_ptr: &wiggle::GuestPtr<'_, u8>,
|
out_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
out_len: guest_types::Size,
|
out_len: guest_types::Size,
|
||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
let out = &mut *out_ptr
|
||||||
|
.as_array(out_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self).symmetric_state_squeeze(symmetric_state_handle.into(), out)?)
|
Ok((&*self).symmetric_state_squeeze(symmetric_state_handle.into(), out)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,8 +267,14 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
data_len: guest_types::Size,
|
data_len: guest_types::Size,
|
||||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
let out = &mut *out_ptr
|
||||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
.as_array(out_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
|
let data = &*data_ptr
|
||||||
|
.as_array(data_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.symmetric_state_encrypt(symmetric_state_handle.into(), out, data)?
|
.symmetric_state_encrypt(symmetric_state_handle.into(), out, data)?
|
||||||
.try_into()?)
|
.try_into()?)
|
||||||
@@ -267,8 +288,14 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
data_len: guest_types::Size,
|
data_len: guest_types::Size,
|
||||||
) -> Result<guest_types::SymmetricTag, guest_types::CryptoErrno> {
|
) -> Result<guest_types::SymmetricTag, guest_types::CryptoErrno> {
|
||||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
let out = &mut *out_ptr
|
||||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
.as_array(out_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
|
let data = &*data_ptr
|
||||||
|
.as_array(data_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.symmetric_state_encrypt_detached(symmetric_state_handle.into(), out, data)?
|
.symmetric_state_encrypt_detached(symmetric_state_handle.into(), out, data)?
|
||||||
.into())
|
.into())
|
||||||
@@ -282,8 +309,14 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
data_len: guest_types::Size,
|
data_len: guest_types::Size,
|
||||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
let out = &mut *out_ptr
|
||||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
.as_array(out_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
|
let data = &*data_ptr
|
||||||
|
.as_array(data_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.symmetric_state_decrypt(symmetric_state_handle.into(), out, data)?
|
.symmetric_state_decrypt(symmetric_state_handle.into(), out, data)?
|
||||||
.try_into()?)
|
.try_into()?)
|
||||||
@@ -299,9 +332,18 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
raw_tag_ptr: &wiggle::GuestPtr<'_, u8>,
|
raw_tag_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
raw_tag_len: guest_types::Size,
|
raw_tag_len: guest_types::Size,
|
||||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
let out = &mut *out_ptr
|
||||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
.as_array(out_len)
|
||||||
let raw_tag: &[u8] = &*raw_tag_ptr.as_array(raw_tag_len).as_slice()?;
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
|
let data = &*data_ptr
|
||||||
|
.as_array(data_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
|
let raw_tag: &[u8] = &*raw_tag_ptr
|
||||||
|
.as_array(raw_tag_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.symmetric_state_decrypt_detached(symmetric_state_handle.into(), out, data, raw_tag)?
|
.symmetric_state_decrypt_detached(symmetric_state_handle.into(), out, data, raw_tag)?
|
||||||
.try_into()?)
|
.try_into()?)
|
||||||
@@ -331,7 +373,10 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
buf_ptr: &wiggle::GuestPtr<'_, u8>,
|
buf_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
buf_len: guest_types::Size,
|
buf_len: guest_types::Size,
|
||||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||||
let buf = &mut *buf_ptr.as_array(buf_len).as_slice_mut()?;
|
let buf = &mut *buf_ptr
|
||||||
|
.as_array(buf_len)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self)
|
Ok((&*self)
|
||||||
.symmetric_tag_pull(symmetric_tag_handle.into(), buf)?
|
.symmetric_tag_pull(symmetric_tag_handle.into(), buf)?
|
||||||
.try_into()?)
|
.try_into()?)
|
||||||
@@ -343,7 +388,10 @@ impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for Wa
|
|||||||
expected_raw_ptr: &wiggle::GuestPtr<'_, u8>,
|
expected_raw_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||||
expected_raw_len: guest_types::Size,
|
expected_raw_len: guest_types::Size,
|
||||||
) -> Result<(), guest_types::CryptoErrno> {
|
) -> Result<(), guest_types::CryptoErrno> {
|
||||||
let expected_raw = &*expected_raw_ptr.as_array(expected_raw_len).as_slice()?;
|
let expected_raw = &*expected_raw_ptr
|
||||||
|
.as_array(expected_raw_len)
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok((&*self).symmetric_tag_verify(symmetric_tag_handle.into(), expected_raw)?)
|
Ok((&*self).symmetric_tag_verify(symmetric_tag_handle.into(), expected_raw)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,8 +80,11 @@ impl<'a> WasiEphemeralNn for WasiNnCtx {
|
|||||||
out_buffer: &GuestPtr<'_, u8>,
|
out_buffer: &GuestPtr<'_, u8>,
|
||||||
out_buffer_max_size: u32,
|
out_buffer_max_size: u32,
|
||||||
) -> Result<u32> {
|
) -> Result<u32> {
|
||||||
let mut destination = out_buffer.as_array(out_buffer_max_size).as_slice_mut()?;
|
|
||||||
if let Some(exec_context) = self.executions.get_mut(exec_context_id) {
|
if let Some(exec_context) = self.executions.get_mut(exec_context_id) {
|
||||||
|
let mut destination = out_buffer
|
||||||
|
.as_array(out_buffer_max_size)
|
||||||
|
.as_slice_mut()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
Ok(exec_context.get_output(index, &mut destination)?)
|
Ok(exec_context.get_output(index, &mut destination)?)
|
||||||
} else {
|
} else {
|
||||||
Err(UsageError::InvalidGraphHandle.into())
|
Err(UsageError::InvalidGraphHandle.into())
|
||||||
|
|||||||
@@ -31,8 +31,15 @@ impl Backend for OpenvinoBackend {
|
|||||||
|
|
||||||
// Read the guest array.
|
// Read the guest array.
|
||||||
let builders = builders.as_ptr();
|
let builders = builders.as_ptr();
|
||||||
let xml = builders.read()?.as_slice()?;
|
let xml = builders
|
||||||
let weights = builders.add(1)?.read()?.as_slice()?;
|
.read()?
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
|
let weights = builders
|
||||||
|
.add(1)?
|
||||||
|
.read()?
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
|
|
||||||
// Construct OpenVINO graph structures: `cnn_network` contains the graph
|
// Construct OpenVINO graph structures: `cnn_network` contains the graph
|
||||||
// structure, `exec_network` can perform inference.
|
// structure, `exec_network` can perform inference.
|
||||||
@@ -78,6 +85,7 @@ impl BackendExecutionContext for OpenvinoExecutionContext {
|
|||||||
let dimensions = tensor
|
let dimensions = tensor
|
||||||
.dimensions
|
.dimensions
|
||||||
.as_slice()?
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)")
|
||||||
.iter()
|
.iter()
|
||||||
.map(|d| *d as usize)
|
.map(|d| *d as usize)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@@ -86,7 +94,10 @@ impl BackendExecutionContext for OpenvinoExecutionContext {
|
|||||||
// TODO There must be some good way to discover the layout here; this
|
// TODO There must be some good way to discover the layout here; this
|
||||||
// should not have to default to NHWC.
|
// should not have to default to NHWC.
|
||||||
let desc = TensorDesc::new(Layout::NHWC, &dimensions, precision);
|
let desc = TensorDesc::new(Layout::NHWC, &dimensions, precision);
|
||||||
let data = tensor.data.as_slice()?;
|
let data = tensor
|
||||||
|
.data
|
||||||
|
.as_slice()?
|
||||||
|
.expect("cannot use with shared memories; see https://github.com/bytecodealliance/wasmtime/issues/5235 (TODO)");
|
||||||
let blob = openvino::Blob::new(&desc, &data)?;
|
let blob = openvino::Blob::new(&desc, &data)?;
|
||||||
|
|
||||||
// Actually assign the blob to the request.
|
// Actually assign the blob to the request.
|
||||||
|
|||||||
@@ -513,88 +513,106 @@ impl<'a, T> GuestPtr<'a, [T]> {
|
|||||||
|
|
||||||
/// Attempts to create a [`GuestSlice<'_, T>`] from this pointer, performing
|
/// Attempts to create a [`GuestSlice<'_, T>`] from this pointer, performing
|
||||||
/// bounds checks and type validation. The `GuestSlice` is a smart pointer
|
/// bounds checks and type validation. The `GuestSlice` is a smart pointer
|
||||||
/// that can be used as a `&[T]` via the `Deref` trait.
|
/// that can be used as a `&[T]` via the `Deref` trait. The region of memory
|
||||||
/// The region of memory backing the slice will be marked as shareably
|
/// backing the slice will be marked as shareably borrowed by the
|
||||||
/// borrowed by the [`GuestMemory`] until the `GuestSlice` is dropped.
|
/// [`GuestMemory`] until the `GuestSlice` is dropped. Multiple shareable
|
||||||
/// Multiple shareable borrows of the same memory are permitted, but only
|
/// borrows of the same memory are permitted, but only one mutable borrow.
|
||||||
/// one mutable borrow.
|
|
||||||
///
|
///
|
||||||
/// This function will return a `GuestSlice` into host memory if all checks
|
/// This function will return a `GuestSlice` into host memory if all checks
|
||||||
/// succeed (valid utf-8, valid pointers, memory is not borrowed, etc). If
|
/// succeed (valid utf-8, valid pointers, memory is not borrowed, etc.). If
|
||||||
/// any checks fail then `GuestError` will be returned.
|
/// any checks fail then `GuestError` will be returned.
|
||||||
pub fn as_slice(&self) -> Result<GuestSlice<'a, T>, GuestError>
|
///
|
||||||
|
/// Additionally, because it is `unsafe` to have a `GuestSlice` of shared
|
||||||
|
/// memory, this function will return `None` in this case.
|
||||||
|
pub fn as_slice(&self) -> Result<Option<GuestSlice<'a, T>>, GuestError>
|
||||||
where
|
where
|
||||||
T: GuestTypeTransparent<'a>,
|
T: GuestTypeTransparent<'a>,
|
||||||
{
|
{
|
||||||
let len = match self.pointer.1.checked_mul(T::guest_size()) {
|
match self.as_unsafe_slice_mut()?.shared_borrow() {
|
||||||
Some(l) => l,
|
UnsafeBorrowResult::Ok(slice) => Ok(Some(slice)),
|
||||||
None => return Err(GuestError::PtrOverflow),
|
UnsafeBorrowResult::Shared(_) => Ok(None),
|
||||||
};
|
UnsafeBorrowResult::Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempts to create a [`GuestSliceMut<'_, T>`] from this pointer,
|
||||||
|
/// performing bounds checks and type validation. The `GuestSliceMut` is a
|
||||||
|
/// smart pointer that can be used as a `&[T]` or a `&mut [T]` via the
|
||||||
|
/// `Deref` and `DerefMut` traits. The region of memory backing the slice
|
||||||
|
/// will be marked as borrowed by the [`GuestMemory`] until the `GuestSlice`
|
||||||
|
/// is dropped.
|
||||||
|
///
|
||||||
|
/// This function will return a `GuestSliceMut` into host memory if all
|
||||||
|
/// checks succeed (valid utf-8, valid pointers, memory is not borrowed,
|
||||||
|
/// etc). If any checks fail then `GuestError` will be returned.
|
||||||
|
///
|
||||||
|
/// Additionally, because it is `unsafe` to have a `GuestSliceMut` of shared
|
||||||
|
/// memory, this function will return `None` in this case.
|
||||||
|
pub fn as_slice_mut(&self) -> Result<Option<GuestSliceMut<'a, T>>, GuestError>
|
||||||
|
where
|
||||||
|
T: GuestTypeTransparent<'a>,
|
||||||
|
{
|
||||||
|
match self.as_unsafe_slice_mut()?.mut_borrow() {
|
||||||
|
UnsafeBorrowResult::Ok(slice) => Ok(Some(slice)),
|
||||||
|
UnsafeBorrowResult::Shared(_) => Ok(None),
|
||||||
|
UnsafeBorrowResult::Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Similar to `as_slice_mut`, this function will attempt to create a smart
|
||||||
|
/// pointer to the WebAssembly linear memory. All validation and Wiggle
|
||||||
|
/// borrow checking is the same, but unlike `as_slice_mut`, the returned
|
||||||
|
/// `&mut` slice can point to WebAssembly shared memory. Though the Wiggle
|
||||||
|
/// borrow checker can guarantee no other Wiggle calls will access this
|
||||||
|
/// slice, it cannot guarantee that another thread is not modifying the
|
||||||
|
/// `&mut` slice in some other way. Thus, access to that slice is marked
|
||||||
|
/// `unsafe`.
|
||||||
|
pub fn as_unsafe_slice_mut(&self) -> Result<UnsafeGuestSlice<'a, T>, GuestError>
|
||||||
|
where
|
||||||
|
T: GuestTypeTransparent<'a>,
|
||||||
|
{
|
||||||
|
// Validate the bounds of the region in the original memory.
|
||||||
|
let len = self.checked_byte_len()?;
|
||||||
let ptr =
|
let ptr =
|
||||||
self.mem
|
self.mem
|
||||||
.validate_size_align(self.pointer.0, T::guest_align(), len)? as *mut T;
|
.validate_size_align(self.pointer.0, T::guest_align(), len)? as *mut T;
|
||||||
|
let region = Region {
|
||||||
let borrow = self.mem.shared_borrow(Region {
|
|
||||||
start: self.pointer.0,
|
start: self.pointer.0,
|
||||||
len,
|
len,
|
||||||
})?;
|
};
|
||||||
|
|
||||||
// Validate all elements in slice.
|
// Validate all elements in slice. `T::validate` is expected to be a
|
||||||
// SAFETY: ptr has been validated by self.mem.validate_size_align
|
// noop for `GuestTypeTransparent` so this check may not be entirely
|
||||||
|
// necessary (TODO).
|
||||||
|
//
|
||||||
|
// SAFETY: `ptr` has been validated by `self.mem.validate_size_align`.
|
||||||
for offs in 0..self.pointer.1 {
|
for offs in 0..self.pointer.1 {
|
||||||
T::validate(unsafe { ptr.add(offs as usize) })?;
|
T::validate(unsafe { ptr.add(offs as usize) })?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: iff there are no overlapping mut borrows it is valid to construct a &[T]
|
Ok(UnsafeGuestSlice {
|
||||||
let ptr = unsafe { slice::from_raw_parts(ptr, self.pointer.1 as usize) };
|
|
||||||
|
|
||||||
Ok(GuestSlice {
|
|
||||||
ptr,
|
ptr,
|
||||||
|
len: self.pointer.1 as usize,
|
||||||
|
region,
|
||||||
mem: self.mem,
|
mem: self.mem,
|
||||||
borrow,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to create a [`GuestSliceMut<'_, T>`] from this pointer, performing
|
/// Copies the data in the guest region into a [`Vec`].
|
||||||
/// bounds checks and type validation. The `GuestSliceMut` is a smart pointer
|
|
||||||
/// that can be used as a `&[T]` or a `&mut [T]` via the `Deref` and `DerefMut`
|
|
||||||
/// traits. The region of memory backing the slice will be marked as borrowed
|
|
||||||
/// by the [`GuestMemory`] until the `GuestSlice` is dropped.
|
|
||||||
///
|
///
|
||||||
/// This function will return a `GuestSliceMut` into host memory if all checks
|
/// This is useful when one cannot use [`GuestPtr::as_slice`], e.g., when
|
||||||
/// succeed (valid utf-8, valid pointers, memory is not borrowed, etc). If
|
/// pointing to a region of WebAssembly shared memory.
|
||||||
/// any checks fail then `GuestError` will be returned.
|
pub fn to_vec(&self) -> Result<Vec<T>, GuestError>
|
||||||
pub fn as_slice_mut(&self) -> Result<GuestSliceMut<'a, T>, GuestError>
|
|
||||||
where
|
where
|
||||||
T: GuestTypeTransparent<'a>,
|
T: GuestTypeTransparent<'a> + Copy + 'a,
|
||||||
{
|
{
|
||||||
let len = match self.pointer.1.checked_mul(T::guest_size()) {
|
let guest_slice = self.as_unsafe_slice_mut()?;
|
||||||
Some(l) => l,
|
let mut vec = Vec::with_capacity(guest_slice.len);
|
||||||
None => return Err(GuestError::PtrOverflow),
|
for offs in 0..guest_slice.len {
|
||||||
};
|
let elem = self.get(offs as u32).expect("already validated the size");
|
||||||
let ptr =
|
vec.push(elem.read()?);
|
||||||
self.mem
|
|
||||||
.validate_size_align(self.pointer.0, T::guest_align(), len)? as *mut T;
|
|
||||||
|
|
||||||
let borrow = self.mem.mut_borrow(Region {
|
|
||||||
start: self.pointer.0,
|
|
||||||
len,
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Validate all elements in slice.
|
|
||||||
// SAFETY: ptr has been validated by self.mem.validate_size_align
|
|
||||||
for offs in 0..self.pointer.1 {
|
|
||||||
T::validate(unsafe { ptr.add(offs as usize) })?;
|
|
||||||
}
|
}
|
||||||
|
Ok(vec)
|
||||||
// SAFETY: iff there are no overlapping borrows it is valid to construct a &mut [T]
|
|
||||||
let ptr = unsafe { slice::from_raw_parts_mut(ptr, self.pointer.1 as usize) };
|
|
||||||
|
|
||||||
Ok(GuestSliceMut {
|
|
||||||
ptr,
|
|
||||||
mem: self.mem,
|
|
||||||
borrow,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copies the data pointed to by `slice` into this guest region.
|
/// Copies the data pointed to by `slice` into this guest region.
|
||||||
@@ -613,14 +631,25 @@ impl<'a, T> GuestPtr<'a, [T]> {
|
|||||||
where
|
where
|
||||||
T: GuestTypeTransparent<'a> + Copy + 'a,
|
T: GuestTypeTransparent<'a> + Copy + 'a,
|
||||||
{
|
{
|
||||||
// bounds check ...
|
// Retrieve the slice of memory to copy to, performing the necessary
|
||||||
let mut self_slice = self.as_slice_mut()?;
|
// bounds checks ...
|
||||||
|
let guest_slice = self.as_unsafe_slice_mut()?;
|
||||||
// ... length check ...
|
// ... length check ...
|
||||||
if self_slice.len() != slice.len() {
|
if guest_slice.len != slice.len() {
|
||||||
return Err(GuestError::SliceLengthsDiffer);
|
return Err(GuestError::SliceLengthsDiffer);
|
||||||
}
|
}
|
||||||
// ... and copy!
|
// ... and copy the bytes.
|
||||||
self_slice.copy_from_slice(slice);
|
match guest_slice.mut_borrow() {
|
||||||
|
UnsafeBorrowResult::Ok(mut dst) => dst.copy_from_slice(slice),
|
||||||
|
UnsafeBorrowResult::Shared(guest_slice) => {
|
||||||
|
// SAFETY: in the shared memory case, we copy and accept that
|
||||||
|
// the guest data may be concurrently modified. TODO: audit that
|
||||||
|
// this use of `std::ptr::copy` is safe with shared memory
|
||||||
|
// (https://github.com/bytecodealliance/wasmtime/issues/4203)
|
||||||
|
unsafe { std::ptr::copy(slice.as_ptr(), guest_slice.ptr, guest_slice.len) };
|
||||||
|
}
|
||||||
|
UnsafeBorrowResult::Err(e) => return Err(e),
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -664,6 +693,17 @@ impl<'a, T> GuestPtr<'a, [T]> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the number of bytes necessary to represent the pointed-to value.
|
||||||
|
fn checked_byte_len(&self) -> Result<u32, GuestError>
|
||||||
|
where
|
||||||
|
T: GuestTypeTransparent<'a>,
|
||||||
|
{
|
||||||
|
match self.pointer.1.checked_mul(T::guest_size()) {
|
||||||
|
Some(l) => Ok(l),
|
||||||
|
None => Err(GuestError::PtrOverflow),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GuestPtr<'a, str> {
|
impl<'a> GuestPtr<'a, str> {
|
||||||
@@ -780,6 +820,7 @@ impl<T: ?Sized + Pointee> fmt::Debug for GuestPtr<'_, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A smart pointer to an shareable slice in guest memory.
|
/// A smart pointer to an shareable slice in guest memory.
|
||||||
|
///
|
||||||
/// Usable as a `&'a [T]` via [`std::ops::Deref`].
|
/// Usable as a `&'a [T]` via [`std::ops::Deref`].
|
||||||
pub struct GuestSlice<'a, T> {
|
pub struct GuestSlice<'a, T> {
|
||||||
ptr: &'a [T],
|
ptr: &'a [T],
|
||||||
@@ -801,6 +842,7 @@ impl<'a, T> Drop for GuestSlice<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A smart pointer to a mutable slice in guest memory.
|
/// A smart pointer to a mutable slice in guest memory.
|
||||||
|
///
|
||||||
/// Usable as a `&'a [T]` via [`std::ops::Deref`] and as a `&'a mut [T]` via
|
/// Usable as a `&'a [T]` via [`std::ops::Deref`] and as a `&'a mut [T]` via
|
||||||
/// [`std::ops::DerefMut`].
|
/// [`std::ops::DerefMut`].
|
||||||
pub struct GuestSliceMut<'a, T> {
|
pub struct GuestSliceMut<'a, T> {
|
||||||
@@ -828,6 +870,108 @@ impl<'a, T> Drop for GuestSliceMut<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A smart pointer to an `unsafe` slice in guest memory.
|
||||||
|
///
|
||||||
|
/// Accessing guest memory (e.g., WebAssembly linear memory) is inherently
|
||||||
|
/// `unsafe`. Even though this structure expects that we will have validated the
|
||||||
|
/// addresses, lengths, and alignment, we must be extra careful to maintain the
|
||||||
|
/// Rust borrowing guarantees if we hand out slices to the underlying memory.
|
||||||
|
/// This is done in two ways:
|
||||||
|
///
|
||||||
|
/// - with shared memory (i.e., memory that may be accessed concurrently by
|
||||||
|
/// multiple threads), we have no guarantee that the underlying data will not
|
||||||
|
/// be changed; thus, we can only hand out slices `unsafe`-ly (TODO:
|
||||||
|
/// eventually with `UnsafeGuestSlice::as_slice`,
|
||||||
|
/// `UnsafeGuestSlice::as_slice_mut`)
|
||||||
|
/// - with non-shared memory, we _can_ maintain the Rust slice guarantees, but
|
||||||
|
/// only by manually performing borrow-checking of the underlying regions that
|
||||||
|
/// are accessed; this kind of borrowing is wrapped up in the [`GuestSlice`]
|
||||||
|
/// and [`GuestSliceMut`] smart pointers (see
|
||||||
|
/// [`UnsafeGuestSlice::shared_borrow`], [`UnsafeGuestSlice::mut_borrow`]).
|
||||||
|
pub struct UnsafeGuestSlice<'a, T> {
|
||||||
|
/// A raw pointer to the bytes in memory.
|
||||||
|
ptr: *mut T,
|
||||||
|
/// The (validated) number of items in the slice.
|
||||||
|
len: usize,
|
||||||
|
/// The (validated) address bounds of the slice in memory.
|
||||||
|
region: Region,
|
||||||
|
/// The original memory.
|
||||||
|
mem: &'a dyn GuestMemory,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> UnsafeGuestSlice<'a, T> {
|
||||||
|
/// Transform an `unsafe` guest slice to a [`GuestSliceMut`].
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This function is safe if and only if:
|
||||||
|
/// - the memory is not shared (it will return `None` in this case) and
|
||||||
|
/// - there are no overlapping mutable borrows for this region.
|
||||||
|
fn shared_borrow(self) -> UnsafeBorrowResult<GuestSlice<'a, T>, Self> {
|
||||||
|
if self.mem.is_shared_memory() {
|
||||||
|
UnsafeBorrowResult::Shared(self)
|
||||||
|
} else {
|
||||||
|
match self.mem.shared_borrow(self.region) {
|
||||||
|
Ok(borrow) => {
|
||||||
|
let ptr = unsafe { slice::from_raw_parts(self.ptr, self.len) };
|
||||||
|
UnsafeBorrowResult::Ok(GuestSlice {
|
||||||
|
ptr,
|
||||||
|
mem: self.mem,
|
||||||
|
borrow,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => UnsafeBorrowResult::Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transform an `unsafe` guest slice to a [`GuestSliceMut`].
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This function is safe if and only if:
|
||||||
|
/// - the memory is not shared (it will return `None` in this case) and
|
||||||
|
/// - there are no overlapping borrows of any kind (shared or mutable) for
|
||||||
|
/// this region.
|
||||||
|
fn mut_borrow(self) -> UnsafeBorrowResult<GuestSliceMut<'a, T>, Self> {
|
||||||
|
if self.mem.is_shared_memory() {
|
||||||
|
UnsafeBorrowResult::Shared(self)
|
||||||
|
} else {
|
||||||
|
match self.mem.mut_borrow(self.region) {
|
||||||
|
Ok(borrow) => {
|
||||||
|
let ptr = unsafe { slice::from_raw_parts_mut(self.ptr, self.len) };
|
||||||
|
UnsafeBorrowResult::Ok(GuestSliceMut {
|
||||||
|
ptr,
|
||||||
|
mem: self.mem,
|
||||||
|
borrow,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => UnsafeBorrowResult::Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A three-way result type for expressing that borrowing from an
|
||||||
|
/// [`UnsafeGuestSlice`] could fail in multiple ways. Retaining the
|
||||||
|
/// [`UnsafeGuestSlice`] in the `Shared` case allows us to reuse it.
|
||||||
|
enum UnsafeBorrowResult<T, S> {
|
||||||
|
/// The borrow succeeded.
|
||||||
|
Ok(T),
|
||||||
|
/// The borrow failed because the underlying memory was shared--we cannot
|
||||||
|
/// safely borrow in this case and return the original unsafe slice.
|
||||||
|
Shared(S),
|
||||||
|
/// The borrow failed for some other reason, e.g., the region was already
|
||||||
|
/// borrowed.
|
||||||
|
Err(GuestError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S> From<GuestError> for UnsafeBorrowResult<T, S> {
|
||||||
|
fn from(e: GuestError) -> Self {
|
||||||
|
UnsafeBorrowResult::Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A smart pointer to an shareable `str` in guest memory.
|
/// A smart pointer to an shareable `str` in guest memory.
|
||||||
/// Usable as a `&'a str` via [`std::ops::Deref`].
|
/// Usable as a `&'a str` via [`std::ops::Deref`].
|
||||||
pub struct GuestStr<'a> {
|
pub struct GuestStr<'a> {
|
||||||
|
|||||||
@@ -147,7 +147,10 @@ impl<'a> crate::wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx<'a> {
|
|||||||
let len: u32 = iov.buf_len;
|
let len: u32 = iov.buf_len;
|
||||||
let buf: GuestPtr<[u8]> = base.as_array(len);
|
let buf: GuestPtr<[u8]> = base.as_array(len);
|
||||||
// GuestSlice will remain borrowed until dropped:
|
// GuestSlice will remain borrowed until dropped:
|
||||||
let slice = buf.as_slice().expect("borrow slice from iovec");
|
let slice = buf
|
||||||
|
.as_slice()
|
||||||
|
.expect("borrow slice from iovec")
|
||||||
|
.expect("expected non-shared memory");
|
||||||
slices.push(slice);
|
slices.push(slice);
|
||||||
}
|
}
|
||||||
println!("iovec slices: [");
|
println!("iovec slices: [");
|
||||||
|
|||||||
Reference in New Issue
Block a user