1use crate::{
2 wasm_engine_t, wasm_functype_t, wasmtime_array_type_t, wasmtime_exn_type_t,
3 wasmtime_struct_type_t,
4};
5use std::mem::{ManuallyDrop, MaybeUninit};
6use wasmtime::{HeapType, RefType, ValType};
7
8pub type wasm_valtype_t = ValType;
9
10wasmtime_c_api_macros::declare_ty!(wasm_valtype_t);
11
12pub type wasm_valkind_t = u8;
13pub const WASM_I32: wasm_valkind_t = 0;
14pub const WASM_I64: wasm_valkind_t = 1;
15pub const WASM_F32: wasm_valkind_t = 2;
16pub const WASM_F64: wasm_valkind_t = 3;
17pub const WASM_EXTERNREF: wasm_valkind_t = 128;
18pub const WASM_FUNCREF: wasm_valkind_t = 129;
19
20#[unsafe(no_mangle)]
21pub extern "C" fn wasm_valtype_new(kind: wasm_valkind_t) -> Box<wasm_valtype_t> {
22 Box::new(match kind {
23 WASM_I32 => ValType::I32,
24 WASM_I64 => ValType::I64,
25 WASM_F32 => ValType::F32,
26 WASM_F64 => ValType::F64,
27 WASM_EXTERNREF => ValType::EXTERNREF,
28 WASM_FUNCREF => ValType::FUNCREF,
29 _ => crate::abort("unexpected value type kind"),
30 })
31}
32
33#[unsafe(no_mangle)]
34pub extern "C" fn wasm_valtype_kind(vt: &wasm_valtype_t) -> wasm_valkind_t {
35 match vt {
36 ValType::I32 => WASM_I32,
37 ValType::I64 => WASM_I64,
38 ValType::F32 => WASM_F32,
39 ValType::F64 => WASM_F64,
40 ValType::V128 => crate::abort("support for v128 "),
42 ValType::Ref(r) => match (r.is_nullable(), r.heap_type()) {
43 (true, HeapType::Extern) => WASM_EXTERNREF,
44 (true, HeapType::Func) => WASM_FUNCREF,
45 _ => crate::abort("support for non-externref and non-funcref references"),
47 },
48 }
49}
50
51#[unsafe(no_mangle)]
52pub extern "C" fn wasmtime_wasm_valtype_v128() -> Box<wasm_valtype_t> {
53 Box::new(ValType::V128)
54}
55
56#[unsafe(no_mangle)]
57pub extern "C" fn wasmtime_wasm_valtype_equal(a: &wasm_valtype_t, b: &wasm_valtype_t) -> bool {
58 ValType::eq(a, b)
59}
60
61#[repr(C, u8)]
62#[derive(Clone)]
63pub enum wasmtime_valtype_t {
64 I32,
65 I64,
66 F32,
67 F64,
68 V128,
69 Ref(wasmtime_reftype_t),
70}
71
72#[unsafe(no_mangle)]
73pub extern "C" fn wasmtime_valtype_new(
74 ty: &wasm_valtype_t,
75 ret: &mut MaybeUninit<wasmtime_valtype_t>,
76) {
77 ret.write(match ty {
78 ValType::I32 => wasmtime_valtype_t::I32,
79 ValType::I64 => wasmtime_valtype_t::I64,
80 ValType::F32 => wasmtime_valtype_t::F32,
81 ValType::F64 => wasmtime_valtype_t::F64,
82 ValType::V128 => wasmtime_valtype_t::V128,
83 ValType::Ref(r) => wasmtime_valtype_t::Ref(wasmtime_reftype_t::from(r)),
84 });
85}
86
87#[unsafe(no_mangle)]
88pub extern "C" fn wasmtime_valtype_clone(
89 ty: &wasmtime_valtype_t,
90 ret: &mut MaybeUninit<wasmtime_valtype_t>,
91) {
92 ret.write(ty.clone());
93}
94
95#[unsafe(no_mangle)]
96pub unsafe extern "C" fn wasmtime_valtype_delete(
97 ret: Option<&mut ManuallyDrop<wasmtime_valtype_t>>,
98) {
99 if let Some(ret) = ret {
100 unsafe {
101 ManuallyDrop::drop(ret);
102 };
103 }
104}
105
106#[unsafe(no_mangle)]
107pub unsafe extern "C" fn wasmtime_valtype_to_wasm(
108 engine: Option<&wasm_engine_t>,
109 r: &wasmtime_valtype_t,
110) -> Box<wasm_valtype_t> {
111 let r = match r {
112 wasmtime_valtype_t::I32 => return Box::new(ValType::I32),
113 wasmtime_valtype_t::I64 => return Box::new(ValType::I64),
114 wasmtime_valtype_t::F32 => return Box::new(ValType::F32),
115 wasmtime_valtype_t::F64 => return Box::new(ValType::F64),
116 wasmtime_valtype_t::V128 => return Box::new(ValType::V128),
117 wasmtime_valtype_t::Ref(r) => r,
118 };
119 let heap_type = match &r.hty {
120 wasmtime_heaptype_t::Extern => HeapType::Extern,
121 wasmtime_heaptype_t::NoExtern => HeapType::NoExtern,
122 wasmtime_heaptype_t::Func => HeapType::Func,
123 wasmtime_heaptype_t::ConcreteFunc(f) => {
124 HeapType::ConcreteFunc(f.ty().ty(&engine.unwrap().engine).clone())
125 }
126 wasmtime_heaptype_t::NoFunc => HeapType::NoFunc,
127 wasmtime_heaptype_t::Any => HeapType::Any,
128 wasmtime_heaptype_t::None => HeapType::None,
129 wasmtime_heaptype_t::Eq => HeapType::Eq,
130 wasmtime_heaptype_t::I31 => HeapType::I31,
131 wasmtime_heaptype_t::Array => HeapType::Array,
132 wasmtime_heaptype_t::ConcreteArray(a) => HeapType::ConcreteArray(a.ty.clone()),
133 wasmtime_heaptype_t::Struct => HeapType::Struct,
134 wasmtime_heaptype_t::ConcreteStruct(s) => HeapType::ConcreteStruct(s.ty.clone()),
135 wasmtime_heaptype_t::Exn => HeapType::Exn,
136 wasmtime_heaptype_t::ConcreteExn(e) => HeapType::ConcreteExn(e.ty.clone()),
137 wasmtime_heaptype_t::NoExn => HeapType::NoExn,
138 };
139 Box::new(ValType::Ref(RefType::new(r.nullable, heap_type)))
140}
141
142#[repr(C, u8)]
143#[derive(Clone)]
144pub enum wasmtime_heaptype_t {
145 Extern,
146 NoExtern,
147 Func,
148 ConcreteFunc(Box<wasm_functype_t>),
149 NoFunc,
150 Any,
151 None,
152 Eq,
153 I31,
154 Array,
155 ConcreteArray(Box<wasmtime_array_type_t>),
156 Struct,
157 ConcreteStruct(Box<wasmtime_struct_type_t>),
158 Exn,
159 ConcreteExn(Box<wasmtime_exn_type_t>),
160 NoExn,
161}
162
163impl From<&HeapType> for wasmtime_heaptype_t {
164 fn from(r: &HeapType) -> Self {
165 match r {
166 HeapType::Extern => Self::Extern,
167 HeapType::NoExtern => Self::NoExtern,
168 HeapType::Func => Self::Func,
169 HeapType::ConcreteFunc(f) => {
170 Self::ConcreteFunc(Box::new(wasm_functype_t::new(f.clone())))
171 }
172 HeapType::NoFunc => Self::NoFunc,
173 HeapType::Any => Self::Any,
174 HeapType::None => Self::None,
175 HeapType::Eq => Self::Eq,
176 HeapType::I31 => Self::I31,
177 HeapType::Array => Self::Array,
178 HeapType::ConcreteArray(a) => {
179 Self::ConcreteArray(Box::new(wasmtime_array_type_t { ty: a.clone() }))
180 }
181 HeapType::Struct => Self::Struct,
182 HeapType::ConcreteStruct(s) => {
183 Self::ConcreteStruct(Box::new(wasmtime_struct_type_t { ty: s.clone() }))
184 }
185 HeapType::Exn => Self::Exn,
186 HeapType::ConcreteExn(e) => {
187 Self::ConcreteExn(Box::new(wasmtime_exn_type_t { ty: e.clone() }))
188 }
189 HeapType::NoExn => Self::NoExn,
190 HeapType::Cont | HeapType::ConcreteCont(_) | HeapType::NoCont => {
191 crate::abort("missing support for contref")
192 }
193 }
194 }
195}
196
197#[unsafe(no_mangle)]
198pub extern "C" fn wasmtime_heaptype_clone(
199 ty: &wasmtime_heaptype_t,
200 ret: &mut MaybeUninit<wasmtime_heaptype_t>,
201) {
202 ret.write(ty.clone());
203}
204
205#[unsafe(no_mangle)]
206pub unsafe extern "C" fn wasmtime_heaptype_delete(
207 ret: Option<&mut ManuallyDrop<wasmtime_heaptype_t>>,
208) {
209 if let Some(ret) = ret {
210 unsafe {
211 ManuallyDrop::drop(ret);
212 }
213 }
214}
215
216#[repr(C)]
217#[derive(Clone)]
218pub struct wasmtime_reftype_t {
219 pub nullable: bool,
220 pub hty: wasmtime_heaptype_t,
221}
222
223impl From<&RefType> for wasmtime_reftype_t {
224 fn from(r: &RefType) -> Self {
225 Self {
226 nullable: r.is_nullable(),
227 hty: r.heap_type().into(),
228 }
229 }
230}
231
232#[unsafe(no_mangle)]
233pub extern "C" fn wasmtime_reftype_clone(
234 ty: &wasmtime_reftype_t,
235 ret: &mut MaybeUninit<wasmtime_reftype_t>,
236) {
237 ret.write(ty.clone());
238}
239
240#[unsafe(no_mangle)]
241pub unsafe extern "C" fn wasmtime_reftype_delete(
242 ret: Option<&mut ManuallyDrop<wasmtime_reftype_t>>,
243) {
244 if let Some(ret) = ret {
245 unsafe {
246 ManuallyDrop::drop(ret);
247 }
248 }
249}