Skip to main content

wasmtime_c_api/types/
val.rs

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        // TODO
41        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            // TODO
46            _ => 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}