Struct ArrayRef
pub struct ArrayRef { /* private fields */ }
Expand description
A reference to a GC-managed array
instance.
WebAssembly array
s are a sequence of elements of some homogeneous
type. The elements length is determined at allocation time — two instances
of the same array type may have different lengths — but, once allocated, an
array’s length can never be resized. An array’s elements are mutable or
constant, depending on the array’s type. This determines whether any array
element can be assigned a new value or not. Each element is either an
unpacked Val
or a packed 8-/16-bit integer. Array elements
are dynamically accessed via indexing; out-of-bounds accesses result in
traps.
Like all WebAssembly references, these are opaque and unforgeable to Wasm:
they cannot be faked and Wasm cannot, for example, cast the integer
0x12345678
into a reference, pretend it is a valid arrayref
, and trick
the host into dereferencing it and segfaulting or worse.
Note that you can also use Rooted<ArrayRef>
and ManuallyRooted<ArrayRef>
as a type parameter with Func::typed
- and
Func::wrap
-style APIs.
§Example
use wasmtime::*;
let mut config = Config::new();
config.wasm_function_references(true);
config.wasm_gc(true);
let engine = Engine::new(&config)?;
let mut store = Store::new(&engine, ());
// Define the type for an array of `i32`s.
let array_ty = ArrayType::new(
store.engine(),
FieldType::new(Mutability::Var, ValType::I32.into()),
);
// Create an allocator for the array type.
let allocator = ArrayRefPre::new(&mut store, array_ty);
{
let mut scope = RootScope::new(&mut store);
// Allocate an instance of the array type.
let len = 36;
let elem = Val::I32(42);
let my_array = match ArrayRef::new(&mut scope, &allocator, &elem, len) {
Ok(s) => s,
Err(e) => match e.downcast::<GcHeapOutOfMemory<()>>() {
// If the heap is out of memory, then do a GC to free up some
// space and try again.
Ok(oom) => {
// Do a GC! Note: in an async context, you'd want to do
// `scope.as_context_mut().gc_async().await`.
scope.as_context_mut().gc(Some(&oom));
// Try again. If the GC heap is still out of memory, then we
// weren't able to free up resources for this allocation, so
// propagate the error.
ArrayRef::new(&mut scope, &allocator, &elem, len)?
}
// Propagate any other kind of error.
Err(e) => return Err(e),
}
};
// That instance's elements should have the initial value.
for i in 0..len {
let val = my_array.get(&mut scope, i)?.unwrap_i32();
assert_eq!(val, 42);
}
// We can set an element to a new value because the type was defined with
// mutable elements (as opposed to const).
my_array.set(&mut scope, 3, Val::I32(1234))?;
let new_val = my_array.get(&mut scope, 3)?.unwrap_i32();
assert_eq!(new_val, 1234);
}
Implementations§
§impl ArrayRef
impl ArrayRef
pub fn new(
store: impl AsContextMut,
allocator: &ArrayRefPre,
elem: &Val,
len: u32,
) -> Result<Rooted<ArrayRef>, Error>
pub fn new( store: impl AsContextMut, allocator: &ArrayRefPre, elem: &Val, len: u32, ) -> Result<Rooted<ArrayRef>, Error>
Allocate a new array
of the given length, with every element
initialized to elem
.
For example, ArrayRef::new(ctx, pre, &Val::I64(9), 3)
allocates the
array [9, 9, 9]
.
This is similar to the array.new
instruction.
§Automatic Garbage Collection
If the GC heap is at capacity, and there isn’t room for allocating this new array, then this method will automatically trigger a synchronous collection in an attempt to free up space in the GC heap.
§Errors
If the given elem
value’s type does not match the allocator
’s array
type’s element type, an error is returned.
If the allocation cannot be satisfied because the GC heap is currently
out of memory, then a GcHeapOutOfMemory<()>
error is returned. The allocation might succeed on a second attempt if
you drop some rooted GC references and try again.
§Panics
Panics if the store
is configured for async; use
[ArrayRef::new_async
][crate::ArrayRef::new_async] to perform
asynchronous allocation instead.
Panics if either the allocator or the elem
value is not associated
with the given store.
pub fn new_fixed(
store: impl AsContextMut,
allocator: &ArrayRefPre,
elems: &[Val],
) -> Result<Rooted<ArrayRef>, Error>
pub fn new_fixed( store: impl AsContextMut, allocator: &ArrayRefPre, elems: &[Val], ) -> Result<Rooted<ArrayRef>, Error>
Synchronously allocate a new array
containing the given elements.
For example, ArrayRef::new_fixed(ctx, pre, &[Val::I64(4), Val::I64(5), Val::I64(6)])
allocates the array [4, 5, 6]
.
This is similar to the array.new_fixed
instruction.
§Automatic Garbage Collection
If the GC heap is at capacity, and there isn’t room for allocating this new array, then this method will automatically trigger a synchronous collection in an attempt to free up space in the GC heap.
§Errors
If any of the elems
values’ type does not match the allocator
’s
array type’s element type, an error is returned.
If the allocation cannot be satisfied because the GC heap is currently
out of memory, then a GcHeapOutOfMemory<()>
error is returned. The allocation might succeed on a second attempt if
you drop some rooted GC references and try again.
§Panics
Panics if the store
is configured for async; use
[ArrayRef::new_fixed_async
][crate::ArrayRef::new_fixed_async] to
perform asynchronous allocation instead.
Panics if the allocator or any of the elems
values are not associated
with the given store.
pub fn elems<'a, T>(
&'a self,
store: impl Into<StoreContextMut<'a, T>>,
) -> Result<impl ExactSizeIterator + 'a, Error>where
T: 'static,
pub fn elems<'a, T>(
&'a self,
store: impl Into<StoreContextMut<'a, T>>,
) -> Result<impl ExactSizeIterator + 'a, Error>where
T: 'static,
pub fn set(
&self,
store: impl AsContextMut,
index: u32,
value: Val,
) -> Result<(), Error>
pub fn set( &self, store: impl AsContextMut, index: u32, value: Val, ) -> Result<(), Error>
Set this array’s index
th element.
§Errors
Returns an error in the following scenarios:
-
When given a value of the wrong type, such as trying to write an
f32
value into an array ofi64
elements. -
When the array elements are not mutable.
-
When
index
is not within the range0..self.len(ctx)
. -
When
value
is a GC reference that has since been unrooted.
§Panics
Panics if either this reference or the given value
is associated with
a different store.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for ArrayRef
impl RefUnwindSafe for ArrayRef
impl Send for ArrayRef
impl Sync for ArrayRef
impl Unpin for ArrayRef
impl UnwindSafe for ArrayRef
Blanket Implementations§
§impl<T> AnySync for T
impl<T> AnySync for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CheckedConversion for T
impl<T> CheckedConversion for T
§impl<T> Conv for T
impl<T> Conv for T
Source§impl<T, U> DefensiveTruncateInto<U> for Twhere
U: DefensiveTruncateFrom<T>,
impl<T, U> DefensiveTruncateInto<U> for Twhere
U: DefensiveTruncateFrom<T>,
Source§fn defensive_truncate_into(self) -> U
fn defensive_truncate_into(self) -> U
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<Src, Dest> IntoTuple<Dest> for Srcwhere
Dest: FromTuple<Src>,
impl<Src, Dest> IntoTuple<Dest> for Srcwhere
Dest: FromTuple<Src>,
fn into_tuple(self) -> Dest
Source§impl<T, Outer> IsWrappedBy<Outer> for T
impl<T, Outer> IsWrappedBy<Outer> for T
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> SaturatedConversion for T
impl<T> SaturatedConversion for T
Source§fn saturated_from<T>(t: T) -> Selfwhere
Self: UniqueSaturatedFrom<T>,
fn saturated_from<T>(t: T) -> Selfwhere
Self: UniqueSaturatedFrom<T>,
Source§fn saturated_into<T>(self) -> Twhere
Self: UniqueSaturatedInto<T>,
fn saturated_into<T>(self) -> Twhere
Self: UniqueSaturatedInto<T>,
T
. Read more§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.§impl<T> TryConv for T
impl<T> TryConv for T
Source§impl<T, U> TryIntoKey<U> for Twhere
U: TryFromKey<T>,
impl<T, U> TryIntoKey<U> for Twhere
U: TryFromKey<T>,
type Error = <U as TryFromKey<T>>::Error
fn try_into_key(self) -> Result<U, <U as TryFromKey<T>>::Error>
Source§impl<S, T> UncheckedInto<T> for Swhere
T: UncheckedFrom<S>,
impl<S, T> UncheckedInto<T> for Swhere
T: UncheckedFrom<S>,
Source§fn unchecked_into(self) -> T
fn unchecked_into(self) -> T
unchecked_from
.Source§impl<T, S> UniqueSaturatedInto<T> for S
impl<T, S> UniqueSaturatedInto<T> for S
Source§fn unique_saturated_into(self) -> T
fn unique_saturated_into(self) -> T
T
.