#[repr(transparent)]pub struct WasmPtr<T, M: MemorySize = Memory32> { /* private fields */ }
Expand description
A zero-cost type that represents a pointer to something in Wasm linear memory.
This type can be used directly in the host function arguments:
pub fn host_import(mut env: FunctionEnvMut<()>, memory: Memory, ptr: WasmPtr<u32>) {
let memory = memory.view(&env);
let derefed_ptr = ptr.deref(&memory);
let inner_val: u32 = derefed_ptr.read().expect("pointer in bounds");
println!("Got {} from Wasm memory address 0x{:X}", inner_val, ptr.offset());
// update the value being pointed to
derefed_ptr.write(inner_val + 1).expect("pointer in bounds");
}
This type can also be used with primitive-filled structs, but be careful of
guarantees required by ValueType
.
// This is safe as the 12 bytes represented by this struct
// are valid for all bit combinations.
#[derive(Copy, Clone, Debug, ValueType)]
#[repr(C)]
struct V3 {
x: f32,
y: f32,
z: f32
}
fn update_vector_3(mut env: FunctionEnvMut<()>, memory: Memory, ptr: WasmPtr<V3>) {
let memory = memory.view(&env);
let derefed_ptr = ptr.deref(&memory);
let mut inner_val: V3 = derefed_ptr.read().expect("pointer in bounds");
println!("Got {:?} from Wasm memory address 0x{:X}", inner_val, ptr.offset());
// update the value being pointed to
inner_val.x = 10.4;
derefed_ptr.write(inner_val).expect("pointer in bounds");
}
Implementations§
source§impl<T, M: MemorySize> WasmPtr<T, M>
impl<T, M: MemorySize> WasmPtr<T, M>
sourcepub fn add_offset(self, offset: M::Offset) -> Result<Self, MemoryAccessError>
pub fn add_offset(self, offset: M::Offset) -> Result<Self, MemoryAccessError>
Calculates an offset from the current pointer address. The argument is
in units of T
.
This method returns an error if an address overflow occurs.
sourcepub fn sub_offset(self, offset: M::Offset) -> Result<Self, MemoryAccessError>
pub fn sub_offset(self, offset: M::Offset) -> Result<Self, MemoryAccessError>
Calculates an offset from the current pointer address. The argument is
in units of T
.
This method returns an error if an address underflow occurs.
source§impl<T: ValueType, M: MemorySize> WasmPtr<T, M>
impl<T: ValueType, M: MemorySize> WasmPtr<T, M>
sourcepub fn deref<'a>(self, view: &'a MemoryView<'_>) -> WasmRef<'a, T>
pub fn deref<'a>(self, view: &'a MemoryView<'_>) -> WasmRef<'a, T>
Creates a WasmRef
from this WasmPtr
which allows reading and
mutating of the value being pointed to.
sourcepub fn read(self, view: &MemoryView<'_>) -> Result<T, MemoryAccessError>
pub fn read(self, view: &MemoryView<'_>) -> Result<T, MemoryAccessError>
Reads the address pointed to by this WasmPtr
in a memory.
sourcepub fn write(self, view: &MemoryView<'_>, val: T) -> Result<(), MemoryAccessError>
pub fn write(self, view: &MemoryView<'_>, val: T) -> Result<(), MemoryAccessError>
Writes to the address pointed to by this WasmPtr
in a memory.
sourcepub fn slice<'a>(
self,
view: &'a MemoryView<'_>,
len: M::Offset
) -> Result<WasmSlice<'a, T>, MemoryAccessError>
pub fn slice<'a>(
self,
view: &'a MemoryView<'_>,
len: M::Offset
) -> Result<WasmSlice<'a, T>, MemoryAccessError>
Creates a WasmSlice
starting at this WasmPtr
which allows reading
and mutating of an array of value being pointed to.
Returns a MemoryAccessError
if the slice length overflows a 64-bit
address.
sourcepub fn read_until(
self,
view: &MemoryView<'_>,
end: impl FnMut(&T) -> bool
) -> Result<Vec<T>, MemoryAccessError>
pub fn read_until(
self,
view: &MemoryView<'_>,
end: impl FnMut(&T) -> bool
) -> Result<Vec<T>, MemoryAccessError>
Reads a sequence of values from this WasmPtr
until a value that
matches the given condition is found.
This last value is not included in the returned vector.
source§impl<M: MemorySize> WasmPtr<u8, M>
impl<M: MemorySize> WasmPtr<u8, M>
sourcepub fn read_utf8_string(
self,
view: &MemoryView<'_>,
len: M::Offset
) -> Result<String, MemoryAccessError>
pub fn read_utf8_string(
self,
view: &MemoryView<'_>,
len: M::Offset
) -> Result<String, MemoryAccessError>
Reads a UTF-8 string from the WasmPtr
with the given length.
This method is safe to call even if the memory is being concurrently modified.
sourcepub fn read_utf8_string_with_nul(
self,
view: &MemoryView<'_>
) -> Result<String, MemoryAccessError>
pub fn read_utf8_string_with_nul(
self,
view: &MemoryView<'_>
) -> Result<String, MemoryAccessError>
Reads a null-terminated UTF-8 string from the WasmPtr
.
This method is safe to call even if the memory is being concurrently modified.
Trait Implementations§
source§impl<T: ValueType, M: MemorySize> FromToNativeWasmType for WasmPtr<T, M>where
<M as MemorySize>::Native: NativeWasmTypeInto,
impl<T: ValueType, M: MemorySize> FromToNativeWasmType for WasmPtr<T, M>where
<M as MemorySize>::Native: NativeWasmTypeInto,
§type Native = <M as MemorySize>::Native
type Native = <M as MemorySize>::Native
source§fn from_native(n: Self::Native) -> Self
fn from_native(n: Self::Native) -> Self
source§fn is_from_store(&self, _store: &impl AsStoreRef) -> bool
fn is_from_store(&self, _store: &impl AsStoreRef) -> bool
source§impl<T: ValueType, M: MemorySize> PartialEq<WasmPtr<T, M>> for WasmPtr<T, M>
impl<T: ValueType, M: MemorySize> PartialEq<WasmPtr<T, M>> for WasmPtr<T, M>
source§impl<T: ValueType, M: MemorySize> ValueType for WasmPtr<T, M>
impl<T: ValueType, M: MemorySize> ValueType for WasmPtr<T, M>
source§fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit<u8>])
fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit<u8>])
self
. It must zero out any bytes which are
uninitialized (e.g. padding bytes).impl<T: ValueType, M: MemorySize> Copy for WasmPtr<T, M>
impl<T: ValueType, M: MemorySize> Eq for WasmPtr<T, M>
Auto Trait Implementations§
impl<T, M> RefUnwindSafe for WasmPtr<T, M>where
T: RefUnwindSafe,
<M as MemorySize>::Offset: RefUnwindSafe,
impl<T, M = Memory32> !Send for WasmPtr<T, M>
impl<T, M = Memory32> !Sync for WasmPtr<T, M>
impl<T, M> Unpin for WasmPtr<T, M>where
<M as MemorySize>::Offset: Unpin,
impl<T, M> UnwindSafe for WasmPtr<T, M>where
T: RefUnwindSafe,
<M as MemorySize>::Offset: UnwindSafe,
Blanket Implementations§
§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
§type ArchivedMetadata = ()
type ArchivedMetadata = ()
§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata
) -> <T as Pointee>::Metadata
fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata
) -> <T as Pointee>::Metadata
§impl<F, W, T, D> Deserialize<With<T, W>, D> for Fwhere
W: DeserializeWith<F, T, D>,
D: Fallible + ?Sized,
F: ?Sized,
impl<F, W, T, D> Deserialize<With<T, W>, D> for Fwhere
W: DeserializeWith<F, T, D>,
D: Fallible + ?Sized,
F: ?Sized,
§fn deserialize(
&self,
deserializer: &mut D
) -> Result<With<T, W>, <D as Fallible>::Error>
fn deserialize(
&self,
deserializer: &mut D
) -> Result<With<T, W>, <D as Fallible>::Error>
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.