Skip to main content

wasmtime_c_api/types/
structref.rs

1use crate::wasm_valtype_t;
2use std::mem::{ManuallyDrop, MaybeUninit};
3use wasmtime::{FieldType, Mutability, StorageType, StructType};
4
5#[repr(C, u8)]
6#[derive(Clone)]
7pub enum wasmtime_storage_type_t {
8    I8,
9    I16,
10    Val(Box<wasm_valtype_t>),
11}
12
13impl From<StorageType> for wasmtime_storage_type_t {
14    fn from(ty: StorageType) -> Self {
15        match ty {
16            StorageType::I8 => Self::I8,
17            StorageType::I16 => Self::I16,
18            StorageType::ValType(ty) => Self::Val(Box::new(ty)),
19        }
20    }
21}
22
23#[unsafe(no_mangle)]
24pub extern "C" fn wasmtime_storage_type_clone(
25    storage: &wasmtime_storage_type_t,
26    out: &mut MaybeUninit<wasmtime_storage_type_t>,
27) {
28    out.write(storage.clone());
29}
30
31#[unsafe(no_mangle)]
32pub unsafe extern "C" fn wasmtime_storage_type_delete(
33    out: Option<&mut ManuallyDrop<wasmtime_storage_type_t>>,
34) {
35    if let Some(out) = out {
36        unsafe {
37            ManuallyDrop::drop(out);
38        }
39    }
40}
41
42#[repr(C)]
43#[derive(Clone)]
44pub struct wasmtime_field_type_t {
45    pub mutable_: bool,
46    pub storage: wasmtime_storage_type_t,
47}
48
49impl From<FieldType> for wasmtime_field_type_t {
50    fn from(field: FieldType) -> Self {
51        let mutable_ = field.mutability() == Mutability::Var;
52        let storage = field.element_type().clone().into();
53        Self { mutable_, storage }
54    }
55}
56
57impl wasmtime_field_type_t {
58    pub(crate) fn to_wasmtime(&self) -> FieldType {
59        let mutability = if self.mutable_ {
60            Mutability::Var
61        } else {
62            Mutability::Const
63        };
64        let storage = match &self.storage {
65            wasmtime_storage_type_t::I8 => StorageType::I8,
66            wasmtime_storage_type_t::I16 => StorageType::I16,
67            wasmtime_storage_type_t::Val(ty) => StorageType::ValType((**ty).clone()),
68        };
69        FieldType::new(mutability, storage)
70    }
71}
72
73#[unsafe(no_mangle)]
74pub extern "C" fn wasmtime_field_type_clone(
75    field: &wasmtime_field_type_t,
76    out: &mut MaybeUninit<wasmtime_field_type_t>,
77) {
78    out.write(field.clone());
79}
80
81#[unsafe(no_mangle)]
82pub unsafe extern "C" fn wasmtime_field_type_delete(
83    out: Option<&mut ManuallyDrop<wasmtime_field_type_t>>,
84) {
85    if let Some(out) = out {
86        unsafe {
87            ManuallyDrop::drop(out);
88        }
89    }
90}
91
92#[derive(Clone)]
93pub struct wasmtime_struct_type_t {
94    pub(crate) ty: StructType,
95}
96wasmtime_c_api_macros::declare_ty!(wasmtime_struct_type_t);
97
98#[unsafe(no_mangle)]
99pub extern "C" fn wasmtime_struct_type_new(
100    engine: &crate::wasm_engine_t,
101    fields: *const wasmtime_field_type_t,
102    nfields: usize,
103) -> Box<wasmtime_struct_type_t> {
104    let fields = unsafe { crate::slice_from_raw_parts(fields, nfields) };
105    let field_types: Vec<FieldType> = fields.iter().map(|f| f.to_wasmtime()).collect();
106    let ty = StructType::new(&engine.engine, field_types).expect("failed to create struct type");
107    Box::new(wasmtime_struct_type_t { ty })
108}
109
110#[unsafe(no_mangle)]
111pub extern "C" fn wasmtime_struct_type_num_fields(ty: &wasmtime_struct_type_t) -> usize {
112    ty.ty.fields().len()
113}
114
115#[unsafe(no_mangle)]
116pub extern "C" fn wasmtime_struct_type_field(
117    ty: &wasmtime_struct_type_t,
118    index: usize,
119    out: &mut MaybeUninit<wasmtime_field_type_t>,
120) -> bool {
121    match ty.ty.field(index) {
122        Some(field) => {
123            out.write(field.into());
124            true
125        }
126        None => false,
127    }
128}