pub struct StructRef { /* private fields */ }
gc
and runtime
only.Expand description
A reference to a GC-managed struct
instance.
WebAssembly struct
s are static, fixed-length, ordered sequences of
fields. Fields are named by index, not by identifier; in this way, they are
similar to Rust’s tuples. Each field is mutable or constant and stores
unpacked Val
s or packed 8-/16-bit integers.
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 structref
, and trick
the host into dereferencing it and segfaulting or worse.
Note that you can also use Rooted<StructRef>
and
ManuallyRooted<StructRef>
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 a struct type.
let struct_ty = StructType::new(
store.engine(),
[FieldType::new(Mutability::Var, StorageType::I8)],
)?;
// Create an allocator for the struct type.
let allocator = StructRefPre::new(&mut store, struct_ty);
{
let mut scope = RootScope::new(&mut store);
// Allocate an instance of the struct type.
let my_struct = match StructRef::new(&mut scope, &allocator, &[Val::I32(42)]) {
Ok(s) => s,
// If the heap is out of memory, then do a GC 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();
StructRef::new(&mut scope, &allocator, &[Val::I32(42)])?
}
Err(e) => return Err(e),
};
// That instance's field should have the expected value.
let val = my_struct.field(&mut scope, 0)?.unwrap_i32();
assert_eq!(val, 42);
// And we can update the field's value because it is a mutable field.
my_struct.set_field(&mut scope, 0, Val::I32(36))?;
let new_val = my_struct.field(&mut scope, 0)?.unwrap_i32();
assert_eq!(new_val, 36);
}
Implementations§
source§impl StructRef
impl StructRef
sourcepub fn new(
store: impl AsContextMut,
allocator: &StructRefPre,
fields: &[Val],
) -> Result<Rooted<StructRef>>
pub fn new( store: impl AsContextMut, allocator: &StructRefPre, fields: &[Val], ) -> Result<Rooted<StructRef>>
Allocate a new struct
and get a reference to it.
§Errors
If the given fields
values’ types do not match the field types of the
allocator
’s struct 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 field values, is not associated with the given store.
sourcepub fn ty(&self, store: impl AsContext) -> Result<StructType>
pub fn ty(&self, store: impl AsContext) -> Result<StructType>
sourcepub fn matches_ty(&self, store: impl AsContext, ty: &StructType) -> Result<bool>
pub fn matches_ty(&self, store: impl AsContext, ty: &StructType) -> Result<bool>
sourcepub fn fields<'a, T: 'a>(
&'a self,
store: impl Into<StoreContextMut<'a, T>>,
) -> Result<impl ExactSizeIterator<Item = Val> + 'a>
pub fn fields<'a, T: 'a>( &'a self, store: impl Into<StoreContextMut<'a, T>>, ) -> Result<impl ExactSizeIterator<Item = Val> + 'a>
sourcepub fn set_field(
&self,
store: impl AsContextMut,
index: usize,
value: Val,
) -> Result<()>
pub fn set_field( &self, store: impl AsContextMut, index: usize, value: Val, ) -> Result<()>
Set this struct’s index
th field.
§Errors
Returns an error in the following scenarios:
-
When given a value of the wrong type, such as trying to set an
f32
field to ani64
value. -
When the field is not mutable.
-
When this struct does not have an
index
th field, i.e.index
is out of bounds. -
When
value
is a GC reference that has since been unrooted.
§Panics
Panics if this reference is associated with a different store.