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,
// If the heap is out of memory, then do a GC to free up some space
// and try again.
Err(e) if e.is::<GcHeapOutOfMemory<()>>() => {
// 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();
// 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§
source§impl ArrayRef
impl ArrayRef
sourcepub fn new(
store: impl AsContextMut,
allocator: &ArrayRefPre,
elem: &Val,
len: u32,
) -> Result<Rooted<ArrayRef>>
pub fn new( store: impl AsContextMut, allocator: &ArrayRefPre, elem: &Val, len: u32, ) -> Result<Rooted<ArrayRef>>
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.
§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, but performing a garbage collection might free up space
such that retrying the allocation afterwards might succeed, then a
GcHeapOutOfMemory<()>
error is returned.
§Panics
Panics if either the allocator or the elem
value is not associated
with the given store.
sourcepub fn new_fixed(
store: impl AsContextMut,
allocator: &ArrayRefPre,
elems: &[Val],
) -> Result<Rooted<ArrayRef>>
pub fn new_fixed( store: impl AsContextMut, allocator: &ArrayRefPre, elems: &[Val], ) -> Result<Rooted<ArrayRef>>
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.
§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, but performing a garbage collection might free up space
such that retrying the allocation afterwards might succeed, then a
GcHeapOutOfMemory<()>
error is returned.
§Panics
Panics if the allocator or any of the elems
values are not associated
with the given store.
sourcepub fn elems<'a, T: 'a>(
&'a self,
store: impl Into<StoreContextMut<'a, T>>,
) -> Result<impl ExactSizeIterator<Item = Val> + 'a>
pub fn elems<'a, T: 'a>( &'a self, store: impl Into<StoreContextMut<'a, T>>, ) -> Result<impl ExactSizeIterator<Item = Val> + 'a>
sourcepub fn set(
&self,
store: impl AsContextMut,
index: u32,
value: Val,
) -> Result<()>
pub fn set( &self, store: impl AsContextMut, index: u32, value: Val, ) -> Result<()>
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§
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> 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