wasmtime_c_api/types/
structref.rs1use 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}