1use crate::{WasmtimeStoreContextMut, abort};
2use std::mem::{ManuallyDrop, MaybeUninit};
3use std::{num::NonZeroU64, os::raw::c_void, ptr};
4use wasmtime::{
5 AnyRef, ArrayRef, ArrayRefPre, ArrayType, EqRef, ExnRef, ExternRef, FieldType, I31, Mutability,
6 OwnedRooted, Ref, RootScope, StorageType, StructRef, StructRefPre, StructType, Val, ValType,
7};
8
9#[derive(Clone)]
22pub struct wasm_ref_t {
23 pub(crate) r: Ref,
24}
25
26wasmtime_c_api_macros::declare_own!(wasm_ref_t);
27
28impl wasm_ref_t {
29 pub(crate) fn new(r: Ref) -> Option<Box<wasm_ref_t>> {
30 if r.is_null() || !r.is_func() {
31 None
32 } else {
33 Some(Box::new(wasm_ref_t { r }))
34 }
35 }
36}
37
38pub(crate) fn ref_to_val(r: &wasm_ref_t) -> Val {
39 Val::from(r.r.clone())
40}
41
42#[unsafe(no_mangle)]
43pub extern "C" fn wasm_ref_copy(r: Option<&wasm_ref_t>) -> Option<Box<wasm_ref_t>> {
44 r.map(|r| Box::new(r.clone()))
45}
46
47#[unsafe(no_mangle)]
48pub extern "C" fn wasm_ref_same(_a: Option<&wasm_ref_t>, _b: Option<&wasm_ref_t>) -> bool {
49 abort("wasm_ref_same")
51}
52
53#[unsafe(no_mangle)]
54pub extern "C" fn wasm_ref_get_host_info(_ref: Option<&wasm_ref_t>) -> *mut c_void {
55 std::ptr::null_mut()
56}
57
58#[unsafe(no_mangle)]
59pub extern "C" fn wasm_ref_set_host_info(_ref: Option<&wasm_ref_t>, _info: *mut c_void) {
60 abort("wasm_ref_set_host_info")
61}
62
63#[unsafe(no_mangle)]
64pub extern "C" fn wasm_ref_set_host_info_with_finalizer(
65 _ref: Option<&wasm_ref_t>,
66 _info: *mut c_void,
67 _finalizer: Option<extern "C" fn(*mut c_void)>,
68) {
69 abort("wasm_ref_set_host_info_with_finalizer")
70}
71
72#[unsafe(no_mangle)]
73pub extern "C" fn wasm_ref_as_extern(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_extern_t> {
74 abort("wasm_ref_as_extern")
75}
76
77#[unsafe(no_mangle)]
78pub extern "C" fn wasm_ref_as_extern_const(
79 _ref: Option<&wasm_ref_t>,
80) -> Option<&crate::wasm_extern_t> {
81 abort("wasm_ref_as_extern_const")
82}
83
84#[unsafe(no_mangle)]
85pub extern "C" fn wasm_ref_as_foreign(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_foreign_t> {
86 abort("wasm_ref_as_foreign")
87}
88
89#[unsafe(no_mangle)]
90pub extern "C" fn wasm_ref_as_foreign_const(
91 _ref: Option<&wasm_ref_t>,
92) -> Option<&crate::wasm_foreign_t> {
93 abort("wasm_ref_as_foreign_const")
94}
95
96#[unsafe(no_mangle)]
97pub extern "C" fn wasm_ref_as_func(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_func_t> {
98 abort("wasm_ref_as_func")
99}
100
101#[unsafe(no_mangle)]
102pub extern "C" fn wasm_ref_as_func_const(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_func_t> {
103 abort("wasm_ref_as_func_const")
104}
105
106#[unsafe(no_mangle)]
107pub extern "C" fn wasm_ref_as_global(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_global_t> {
108 abort("wasm_ref_as_global")
109}
110
111#[unsafe(no_mangle)]
112pub extern "C" fn wasm_ref_as_global_const(
113 _ref: Option<&wasm_ref_t>,
114) -> Option<&crate::wasm_global_t> {
115 abort("wasm_ref_as_global_const")
116}
117
118#[unsafe(no_mangle)]
119pub extern "C" fn wasm_ref_as_instance(
120 _ref: Option<&wasm_ref_t>,
121) -> Option<&crate::wasm_instance_t> {
122 abort("wasm_ref_as_instance")
123}
124
125#[unsafe(no_mangle)]
126pub extern "C" fn wasm_ref_as_instance_const(
127 _ref: Option<&wasm_ref_t>,
128) -> Option<&crate::wasm_instance_t> {
129 abort("wasm_ref_as_instance_const")
130}
131
132#[unsafe(no_mangle)]
133pub extern "C" fn wasm_ref_as_memory(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_memory_t> {
134 abort("wasm_ref_as_memory")
135}
136
137#[unsafe(no_mangle)]
138pub extern "C" fn wasm_ref_as_memory_const(
139 _ref: Option<&wasm_ref_t>,
140) -> Option<&crate::wasm_memory_t> {
141 abort("wasm_ref_as_memory_const")
142}
143
144#[unsafe(no_mangle)]
145pub extern "C" fn wasm_ref_as_module(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_module_t> {
146 abort("wasm_ref_as_module")
147}
148
149#[unsafe(no_mangle)]
150pub extern "C" fn wasm_ref_as_module_const(
151 _ref: Option<&wasm_ref_t>,
152) -> Option<&crate::wasm_module_t> {
153 abort("wasm_ref_as_module_const")
154}
155
156#[unsafe(no_mangle)]
157pub extern "C" fn wasm_ref_as_table(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_table_t> {
158 abort("wasm_ref_as_table")
159}
160
161#[unsafe(no_mangle)]
162pub extern "C" fn wasm_ref_as_table_const(
163 _ref: Option<&wasm_ref_t>,
164) -> Option<&crate::wasm_table_t> {
165 abort("wasm_ref_as_table_const")
166}
167
168#[unsafe(no_mangle)]
169pub extern "C" fn wasm_ref_as_trap(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_trap_t> {
170 abort("wasm_ref_as_trap")
171}
172
173#[unsafe(no_mangle)]
174pub extern "C" fn wasm_ref_as_trap_const(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_trap_t> {
175 abort("wasm_ref_as_trap_const")
176}
177
178#[derive(Clone)]
179#[repr(C)]
180pub struct wasm_foreign_t {}
181
182wasmtime_c_api_macros::declare_ref!(wasm_foreign_t);
183
184#[unsafe(no_mangle)]
185pub extern "C" fn wasm_foreign_new(_store: &crate::wasm_store_t) -> Box<wasm_foreign_t> {
186 abort("wasm_foreign_new")
187}
188
189macro_rules! ref_wrapper {
198 ($wasmtime:ident => $c:ident) => {
199 pub struct $c {
200 store_id: u64,
201 a: u32,
202 b: u32,
203 c: *const (),
204 }
205
206 impl $c {
207 pub unsafe fn as_wasmtime(&self) -> Option<OwnedRooted<$wasmtime>> {
208 let store_id = NonZeroU64::new(self.store_id)?;
209 Some(OwnedRooted::from_borrowed_raw_parts_for_c_api(
210 store_id, self.a, self.b, self.c,
211 ))
212 }
213
214 pub unsafe fn into_wasmtime(self) -> Option<OwnedRooted<$wasmtime>> {
215 ManuallyDrop::new(self).to_owned()
216 }
217
218 unsafe fn to_owned(&self) -> Option<OwnedRooted<$wasmtime>> {
219 let store_id = NonZeroU64::new(self.store_id)?;
220 Some(OwnedRooted::from_owned_raw_parts_for_c_api(
221 store_id, self.a, self.b, self.c,
222 ))
223 }
224 }
225
226 impl Drop for $c {
227 fn drop(&mut self) {
228 unsafe {
229 let _ = self.to_owned();
230 }
231 }
232 }
233
234 impl From<Option<OwnedRooted<$wasmtime>>> for $c {
235 fn from(rooted: Option<OwnedRooted<$wasmtime>>) -> $c {
236 let mut ret = $c {
237 store_id: 0,
238 a: 0,
239 b: 0,
240 c: core::ptr::null(),
241 };
242 if let Some(rooted) = rooted {
243 let (store_id, a, b, c) = rooted.into_parts_for_c_api();
244 ret.store_id = store_id.get();
245 ret.a = a;
246 ret.b = b;
247 ret.c = c;
248 }
249 ret
250 }
251 }
252
253 impl From<OwnedRooted<$wasmtime>> for $c {
254 fn from(rooted: OwnedRooted<$wasmtime>) -> $c {
255 Self::from(Some(rooted))
256 }
257 }
258
259 unsafe impl Send for $c {}
264 unsafe impl Sync for $c {}
265 };
266}
267
268ref_wrapper!(AnyRef => wasmtime_anyref_t);
269ref_wrapper!(ExternRef => wasmtime_externref_t);
270ref_wrapper!(EqRef => wasmtime_eqref_t);
271ref_wrapper!(StructRef => wasmtime_structref_t);
272ref_wrapper!(ExnRef => wasmtime_exnref_t);
273
274pub struct wasmtime_struct_type_t {
276 ty: StructType,
277}
278wasmtime_c_api_macros::declare_own!(wasmtime_struct_type_t);
279
280pub struct wasmtime_struct_ref_pre_t {
281 pre: StructRefPre,
282}
283wasmtime_c_api_macros::declare_own!(wasmtime_struct_ref_pre_t);
284
285ref_wrapper!(ArrayRef => wasmtime_arrayref_t);
286
287pub struct wasmtime_array_type_t {
288 ty: ArrayType,
289}
290wasmtime_c_api_macros::declare_own!(wasmtime_array_type_t);
291
292pub struct wasmtime_array_ref_pre_t {
293 pre: ArrayRefPre,
294}
295wasmtime_c_api_macros::declare_own!(wasmtime_array_ref_pre_t);
296
297#[unsafe(no_mangle)]
298pub unsafe extern "C" fn wasmtime_anyref_clone(
299 anyref: Option<&wasmtime_anyref_t>,
300 out: &mut MaybeUninit<wasmtime_anyref_t>,
301) {
302 let anyref = anyref.and_then(|a| a.as_wasmtime());
303 crate::initialize(out, anyref.into());
304}
305
306#[unsafe(no_mangle)]
307pub unsafe extern "C" fn wasmtime_anyref_unroot(val: Option<&mut ManuallyDrop<wasmtime_anyref_t>>) {
308 if let Some(val) = val {
309 unsafe {
310 ManuallyDrop::drop(val);
311 }
312 }
313}
314
315#[unsafe(no_mangle)]
316pub unsafe extern "C" fn wasmtime_anyref_to_raw(
317 cx: WasmtimeStoreContextMut<'_>,
318 val: Option<&wasmtime_anyref_t>,
319) -> u32 {
320 val.and_then(|v| v.as_wasmtime())
321 .and_then(|e| e.to_raw(cx).ok())
322 .unwrap_or_default()
323}
324
325#[unsafe(no_mangle)]
326pub unsafe extern "C" fn wasmtime_anyref_from_raw(
327 cx: WasmtimeStoreContextMut<'_>,
328 raw: u32,
329 val: &mut MaybeUninit<wasmtime_anyref_t>,
330) {
331 let mut scope = RootScope::new(cx);
332 let anyref =
333 AnyRef::from_raw(&mut scope, raw).map(|a| a.to_owned_rooted(&mut scope).expect("in scope"));
334 crate::initialize(val, anyref.into());
335}
336
337#[unsafe(no_mangle)]
338pub extern "C" fn wasmtime_anyref_from_i31(
339 cx: WasmtimeStoreContextMut<'_>,
340 val: u32,
341 out: &mut MaybeUninit<wasmtime_anyref_t>,
342) {
343 let mut scope = RootScope::new(cx);
344 let anyref = AnyRef::from_i31(&mut scope, I31::wrapping_u32(val));
345 let anyref = anyref.to_owned_rooted(&mut scope).expect("in scope");
346 crate::initialize(out, Some(anyref).into())
347}
348
349#[unsafe(no_mangle)]
350pub unsafe extern "C" fn wasmtime_anyref_is_i31(
351 cx: WasmtimeStoreContextMut<'_>,
352 anyref: Option<&wasmtime_anyref_t>,
353) -> bool {
354 match anyref.and_then(|a| a.as_wasmtime()) {
355 Some(anyref) => anyref.is_i31(&cx).expect("OwnedRooted always in scope"),
356 None => false,
357 }
358}
359
360#[unsafe(no_mangle)]
361pub unsafe extern "C" fn wasmtime_anyref_i31_get_u(
362 cx: WasmtimeStoreContextMut<'_>,
363 anyref: Option<&wasmtime_anyref_t>,
364 dst: &mut MaybeUninit<u32>,
365) -> bool {
366 match anyref.and_then(|a| a.as_wasmtime()) {
367 Some(anyref) if anyref.is_i31(&cx).expect("OwnedRooted always in scope") => {
368 let val = anyref
369 .unwrap_i31(&cx)
370 .expect("OwnedRooted always in scope")
371 .get_u32();
372 crate::initialize(dst, val);
373 true
374 }
375 _ => false,
376 }
377}
378
379#[unsafe(no_mangle)]
380pub unsafe extern "C" fn wasmtime_anyref_i31_get_s(
381 cx: WasmtimeStoreContextMut<'_>,
382 anyref: Option<&wasmtime_anyref_t>,
383 dst: &mut MaybeUninit<i32>,
384) -> bool {
385 match anyref.and_then(|a| a.as_wasmtime()) {
386 Some(anyref) if anyref.is_i31(&cx).expect("OwnedRooted always in scope") => {
387 let val = anyref
388 .unwrap_i31(&cx)
389 .expect("OwnedRooted always in scope")
390 .get_i32();
391 crate::initialize(dst, val);
392 true
393 }
394 _ => false,
395 }
396}
397
398#[unsafe(no_mangle)]
399pub extern "C" fn wasmtime_externref_new(
400 cx: WasmtimeStoreContextMut<'_>,
401 data: *mut c_void,
402 finalizer: Option<extern "C" fn(*mut c_void)>,
403 out: &mut MaybeUninit<wasmtime_externref_t>,
404) -> bool {
405 let mut scope = RootScope::new(cx);
406 let e = match ExternRef::new(&mut scope, crate::ForeignData { data, finalizer }) {
407 Ok(e) => e,
408 Err(_) => return false,
409 };
410 let e = e.to_owned_rooted(&mut scope).expect("in scope");
411 crate::initialize(out, Some(e).into());
412 true
413}
414
415#[unsafe(no_mangle)]
416pub unsafe extern "C" fn wasmtime_externref_data(
417 cx: WasmtimeStoreContextMut<'_>,
418 externref: Option<&wasmtime_externref_t>,
419) -> *mut c_void {
420 externref
421 .and_then(|e| e.as_wasmtime())
422 .and_then(|e| {
423 let data = e.data(cx).ok()??;
424 Some(data.downcast_ref::<crate::ForeignData>().unwrap().data)
425 })
426 .unwrap_or(ptr::null_mut())
427}
428
429#[unsafe(no_mangle)]
430pub unsafe extern "C" fn wasmtime_externref_clone(
431 externref: Option<&wasmtime_externref_t>,
432 out: &mut MaybeUninit<wasmtime_externref_t>,
433) {
434 let externref = externref.and_then(|e| e.as_wasmtime());
435 crate::initialize(out, externref.into());
436}
437
438#[unsafe(no_mangle)]
439pub unsafe extern "C" fn wasmtime_externref_unroot(
440 val: Option<&mut ManuallyDrop<wasmtime_externref_t>>,
441) {
442 if let Some(val) = val {
443 unsafe {
444 ManuallyDrop::drop(val);
445 }
446 }
447}
448
449#[unsafe(no_mangle)]
450pub unsafe extern "C" fn wasmtime_externref_to_raw(
451 cx: WasmtimeStoreContextMut<'_>,
452 val: Option<&wasmtime_externref_t>,
453) -> u32 {
454 val.and_then(|e| e.as_wasmtime())
455 .and_then(|e| e.to_raw(cx).ok())
456 .unwrap_or_default()
457}
458
459#[unsafe(no_mangle)]
460pub unsafe extern "C" fn wasmtime_externref_from_raw(
461 cx: WasmtimeStoreContextMut<'_>,
462 raw: u32,
463 val: &mut MaybeUninit<wasmtime_externref_t>,
464) {
465 let mut scope = RootScope::new(cx);
466 let rooted = ExternRef::from_raw(&mut scope, raw)
467 .map(|e| e.to_owned_rooted(&mut scope).expect("in scope"));
468 crate::initialize(val, rooted.into());
469}
470
471#[unsafe(no_mangle)]
472pub unsafe extern "C" fn wasmtime_exnref_clone(
473 exnref: Option<&wasmtime_exnref_t>,
474 out: &mut MaybeUninit<wasmtime_exnref_t>,
475) {
476 let exnref = exnref.and_then(|e| e.as_wasmtime());
477 crate::initialize(out, exnref.into());
478}
479
480#[unsafe(no_mangle)]
481pub unsafe extern "C" fn wasmtime_exnref_unroot(val: Option<&mut ManuallyDrop<wasmtime_exnref_t>>) {
482 if let Some(val) = val {
483 unsafe {
484 ManuallyDrop::drop(val);
485 }
486 }
487}
488
489#[unsafe(no_mangle)]
490pub unsafe extern "C" fn wasmtime_eqref_clone(
491 eqref: Option<&wasmtime_eqref_t>,
492 out: &mut MaybeUninit<wasmtime_eqref_t>,
493) {
494 let eqref = eqref.and_then(|e| e.as_wasmtime());
495 crate::initialize(out, eqref.into());
496}
497
498#[unsafe(no_mangle)]
499pub unsafe extern "C" fn wasmtime_eqref_unroot(val: Option<&mut ManuallyDrop<wasmtime_eqref_t>>) {
500 if let Some(val) = val {
501 unsafe {
502 ManuallyDrop::drop(val);
503 }
504 }
505}
506
507#[unsafe(no_mangle)]
508pub unsafe extern "C" fn wasmtime_eqref_to_anyref(
509 eqref: Option<&wasmtime_eqref_t>,
510 out: &mut MaybeUninit<wasmtime_anyref_t>,
511) {
512 let anyref = eqref.and_then(|e| e.as_wasmtime()).map(|e| e.to_anyref());
513 crate::initialize(out, anyref.into());
514}
515
516#[unsafe(no_mangle)]
517pub extern "C" fn wasmtime_eqref_from_i31(
518 cx: WasmtimeStoreContextMut<'_>,
519 val: u32,
520 out: &mut MaybeUninit<wasmtime_eqref_t>,
521) {
522 let mut scope = RootScope::new(cx);
523 let eqref = EqRef::from_i31(&mut scope, I31::wrapping_u32(val));
524 let eqref = eqref.to_owned_rooted(&mut scope).expect("in scope");
525 crate::initialize(out, Some(eqref).into())
526}
527
528#[unsafe(no_mangle)]
529pub unsafe extern "C" fn wasmtime_eqref_is_i31(
530 cx: WasmtimeStoreContextMut<'_>,
531 eqref: Option<&wasmtime_eqref_t>,
532) -> bool {
533 match eqref.and_then(|e| e.as_wasmtime()) {
534 Some(eqref) => eqref.is_i31(&cx).expect("OwnedRooted always in scope"),
535 None => false,
536 }
537}
538
539#[unsafe(no_mangle)]
540pub unsafe extern "C" fn wasmtime_eqref_i31_get_u(
541 cx: WasmtimeStoreContextMut<'_>,
542 eqref: Option<&wasmtime_eqref_t>,
543 dst: &mut MaybeUninit<u32>,
544) -> bool {
545 let mut scope = RootScope::new(cx);
546 if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
547 if let Some(val) = eqref.as_i31(&mut scope).expect("in scope") {
548 crate::initialize(dst, val.get_u32());
549 return true;
550 }
551 }
552 false
553}
554
555#[unsafe(no_mangle)]
556pub unsafe extern "C" fn wasmtime_eqref_i31_get_s(
557 cx: WasmtimeStoreContextMut<'_>,
558 eqref: Option<&wasmtime_eqref_t>,
559 dst: &mut MaybeUninit<i32>,
560) -> bool {
561 let mut scope = RootScope::new(cx);
562 if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
563 if let Some(val) = eqref.as_i31(&mut scope).expect("in scope") {
564 crate::initialize(dst, val.get_i32());
565 return true;
566 }
567 }
568 false
569}
570
571pub type wasmtime_storage_kind_t = u8;
572pub const WASMTIME_STORAGE_KIND_I8: wasmtime_storage_kind_t = 9;
573pub const WASMTIME_STORAGE_KIND_I16: wasmtime_storage_kind_t = 10;
574
575#[repr(C)]
576pub struct wasmtime_field_type_t {
577 pub kind: wasmtime_storage_kind_t,
578 pub mutable_: bool,
579}
580
581fn field_type_from_c(ft: &wasmtime_field_type_t) -> FieldType {
582 let mutability = if ft.mutable_ {
583 Mutability::Var
584 } else {
585 Mutability::Const
586 };
587 let storage = match ft.kind {
588 WASMTIME_STORAGE_KIND_I8 => StorageType::I8,
589 WASMTIME_STORAGE_KIND_I16 => StorageType::I16,
590 crate::WASMTIME_I32 => StorageType::ValType(ValType::I32),
591 crate::WASMTIME_I64 => StorageType::ValType(ValType::I64),
592 crate::WASMTIME_F32 => StorageType::ValType(ValType::F32),
593 crate::WASMTIME_F64 => StorageType::ValType(ValType::F64),
594 crate::WASMTIME_V128 => StorageType::ValType(ValType::V128),
595 crate::WASMTIME_FUNCREF => StorageType::ValType(ValType::FUNCREF),
596 crate::WASMTIME_EXTERNREF => StorageType::ValType(ValType::EXTERNREF),
597 crate::WASMTIME_ANYREF => StorageType::ValType(ValType::ANYREF),
598 crate::WASMTIME_EXNREF => StorageType::ValType(ValType::EXNREF),
599 other => panic!("unknown wasmtime_storage_kind_t: {other}"),
600 };
601 FieldType::new(mutability, storage)
602}
603
604#[unsafe(no_mangle)]
605pub extern "C" fn wasmtime_struct_type_new(
606 engine: &crate::wasm_engine_t,
607 fields: *const wasmtime_field_type_t,
608 nfields: usize,
609) -> Box<wasmtime_struct_type_t> {
610 let fields = if nfields == 0 {
611 &[]
612 } else {
613 unsafe { std::slice::from_raw_parts(fields, nfields) }
614 };
615 let field_types: Vec<FieldType> = fields.iter().map(field_type_from_c).collect();
616 let ty = StructType::new(&engine.engine, field_types).expect("failed to create struct type");
617 Box::new(wasmtime_struct_type_t { ty })
618}
619
620#[unsafe(no_mangle)]
621pub extern "C" fn wasmtime_struct_ref_pre_new(
622 cx: WasmtimeStoreContextMut<'_>,
623 ty: &wasmtime_struct_type_t,
624) -> Box<wasmtime_struct_ref_pre_t> {
625 let pre = StructRefPre::new(cx, ty.ty.clone());
626 Box::new(wasmtime_struct_ref_pre_t { pre })
627}
628
629#[unsafe(no_mangle)]
630pub unsafe extern "C" fn wasmtime_structref_new(
631 mut cx: WasmtimeStoreContextMut<'_>,
632 pre: &wasmtime_struct_ref_pre_t,
633 fields: *const crate::wasmtime_val_t,
634 nfields: usize,
635 out: &mut MaybeUninit<wasmtime_structref_t>,
636) -> Option<Box<crate::wasmtime_error_t>> {
637 let c_fields = if nfields == 0 {
638 &[]
639 } else {
640 std::slice::from_raw_parts(fields, nfields)
641 };
642 let mut scope = RootScope::new(&mut cx);
643 let vals: Vec<Val> = c_fields.iter().map(|v| v.to_val(&mut scope)).collect();
644 match StructRef::new(&mut scope, &pre.pre, &vals) {
645 Ok(structref) => {
646 let owned = structref
647 .to_owned_rooted(&mut scope)
648 .expect("just allocated");
649 crate::initialize(out, Some(owned).into());
650 None
651 }
652 Err(e) => {
653 crate::initialize(out, None::<OwnedRooted<StructRef>>.into());
654 Some(Box::new(e.into()))
655 }
656 }
657}
658
659#[unsafe(no_mangle)]
660pub unsafe extern "C" fn wasmtime_structref_clone(
661 structref: Option<&wasmtime_structref_t>,
662 out: &mut MaybeUninit<wasmtime_structref_t>,
663) {
664 let structref = structref.and_then(|s| s.as_wasmtime());
665 crate::initialize(out, structref.into());
666}
667
668#[unsafe(no_mangle)]
669pub unsafe extern "C" fn wasmtime_structref_unroot(
670 structref: Option<&mut ManuallyDrop<wasmtime_structref_t>>,
671) {
672 if let Some(structref) = structref {
673 ManuallyDrop::drop(structref);
674 }
675}
676
677#[unsafe(no_mangle)]
678pub unsafe extern "C" fn wasmtime_structref_to_anyref(
679 structref: Option<&wasmtime_structref_t>,
680 out: &mut MaybeUninit<wasmtime_anyref_t>,
681) {
682 let anyref = structref
683 .and_then(|s| s.as_wasmtime())
684 .map(|s| s.to_anyref());
685 crate::initialize(out, anyref.into());
686}
687
688#[unsafe(no_mangle)]
689pub unsafe extern "C" fn wasmtime_structref_to_eqref(
690 structref: Option<&wasmtime_structref_t>,
691 out: &mut MaybeUninit<wasmtime_eqref_t>,
692) {
693 let eqref = structref
694 .and_then(|s| s.as_wasmtime())
695 .map(|s| s.to_eqref());
696 crate::initialize(out, eqref.into());
697}
698
699#[unsafe(no_mangle)]
700pub unsafe extern "C" fn wasmtime_structref_field(
701 mut cx: WasmtimeStoreContextMut<'_>,
702 structref: Option<&wasmtime_structref_t>,
703 index: usize,
704 out: &mut MaybeUninit<crate::wasmtime_val_t>,
705) -> Option<Box<crate::wasmtime_error_t>> {
706 let structref = structref
707 .and_then(|s| s.as_wasmtime())
708 .expect("non-null structref required");
709 let mut scope = RootScope::new(&mut cx);
710 let rooted = structref.to_rooted(&mut scope);
711 match rooted.field(&mut scope, index) {
712 Ok(val) => {
713 let c_val = crate::wasmtime_val_t::from_val(&mut scope, val);
714 crate::initialize(out, c_val);
715 None
716 }
717 Err(e) => Some(Box::new(e.into())),
718 }
719}
720
721#[unsafe(no_mangle)]
722pub unsafe extern "C" fn wasmtime_structref_set_field(
723 mut cx: WasmtimeStoreContextMut<'_>,
724 structref: Option<&wasmtime_structref_t>,
725 index: usize,
726 val: &crate::wasmtime_val_t,
727) -> Option<Box<crate::wasmtime_error_t>> {
728 let structref = structref
729 .and_then(|s| s.as_wasmtime())
730 .expect("non-null structref required");
731 let mut scope = RootScope::new(&mut cx);
732 let rooted = structref.to_rooted(&mut scope);
733 let rust_val = val.to_val(&mut scope);
734 match rooted.set_field(&mut scope, index, rust_val) {
735 Ok(()) => None,
736 Err(e) => Some(Box::new(e.into())),
737 }
738}
739
740#[unsafe(no_mangle)]
741pub unsafe extern "C" fn wasmtime_eqref_is_struct(
742 cx: WasmtimeStoreContextMut<'_>,
743 eqref: Option<&wasmtime_eqref_t>,
744) -> bool {
745 match eqref.and_then(|e| e.as_wasmtime()) {
746 Some(eqref) => eqref.is_struct(&cx).expect("OwnedRooted always in scope"),
747 None => false,
748 }
749}
750
751#[unsafe(no_mangle)]
752pub unsafe extern "C" fn wasmtime_eqref_as_struct(
753 mut cx: WasmtimeStoreContextMut<'_>,
754 eqref: Option<&wasmtime_eqref_t>,
755 out: &mut MaybeUninit<wasmtime_structref_t>,
756) -> bool {
757 if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
758 let mut scope = RootScope::new(&mut cx);
759 let rooted = eqref.to_rooted(&mut scope);
760 if let Ok(Some(structref)) = rooted.as_struct(&scope) {
761 let owned = structref.to_owned_rooted(&mut scope).expect("in scope");
762 crate::initialize(out, Some(owned).into());
763 return true;
764 }
765 }
766 crate::initialize(out, None::<OwnedRooted<StructRef>>.into());
767 false
768}
769
770#[unsafe(no_mangle)]
771pub extern "C" fn wasmtime_array_type_new(
772 engine: &crate::wasm_engine_t,
773 field: &wasmtime_field_type_t,
774) -> Box<wasmtime_array_type_t> {
775 let ft = field_type_from_c(field);
776 let ty = ArrayType::new(&engine.engine, ft);
777 Box::new(wasmtime_array_type_t { ty })
778}
779
780#[unsafe(no_mangle)]
781pub extern "C" fn wasmtime_array_ref_pre_new(
782 cx: WasmtimeStoreContextMut<'_>,
783 ty: &wasmtime_array_type_t,
784) -> Box<wasmtime_array_ref_pre_t> {
785 let pre = ArrayRefPre::new(cx, ty.ty.clone());
786 Box::new(wasmtime_array_ref_pre_t { pre })
787}
788
789#[unsafe(no_mangle)]
790pub unsafe extern "C" fn wasmtime_arrayref_new(
791 mut cx: WasmtimeStoreContextMut<'_>,
792 pre: &wasmtime_array_ref_pre_t,
793 elem: &crate::wasmtime_val_t,
794 len: u32,
795 out: &mut MaybeUninit<wasmtime_arrayref_t>,
796) -> Option<Box<crate::wasmtime_error_t>> {
797 let mut scope = RootScope::new(&mut cx);
798 let val = elem.to_val(&mut scope);
799 match ArrayRef::new(&mut scope, &pre.pre, &val, len) {
800 Ok(arrayref) => {
801 let owned = arrayref
802 .to_owned_rooted(&mut scope)
803 .expect("just allocated");
804 crate::initialize(out, Some(owned).into());
805 None
806 }
807 Err(e) => {
808 crate::initialize(out, None::<OwnedRooted<ArrayRef>>.into());
809 Some(Box::new(e.into()))
810 }
811 }
812}
813
814#[unsafe(no_mangle)]
815pub unsafe extern "C" fn wasmtime_arrayref_clone(
816 arrayref: Option<&wasmtime_arrayref_t>,
817 out: &mut MaybeUninit<wasmtime_arrayref_t>,
818) {
819 let arrayref = arrayref.and_then(|a| a.as_wasmtime());
820 crate::initialize(out, arrayref.into());
821}
822
823#[unsafe(no_mangle)]
824pub unsafe extern "C" fn wasmtime_arrayref_unroot(
825 arrayref: Option<&mut ManuallyDrop<wasmtime_arrayref_t>>,
826) {
827 if let Some(arrayref) = arrayref {
828 ManuallyDrop::drop(arrayref);
829 }
830}
831
832#[unsafe(no_mangle)]
833pub unsafe extern "C" fn wasmtime_arrayref_to_anyref(
834 arrayref: Option<&wasmtime_arrayref_t>,
835 out: &mut MaybeUninit<wasmtime_anyref_t>,
836) {
837 let anyref = arrayref
838 .and_then(|a| a.as_wasmtime())
839 .map(|a| a.to_anyref());
840 crate::initialize(out, anyref.into());
841}
842
843#[unsafe(no_mangle)]
844pub unsafe extern "C" fn wasmtime_arrayref_to_eqref(
845 arrayref: Option<&wasmtime_arrayref_t>,
846 out: &mut MaybeUninit<wasmtime_eqref_t>,
847) {
848 let eqref = arrayref.and_then(|a| a.as_wasmtime()).map(|a| a.to_eqref());
849 crate::initialize(out, eqref.into());
850}
851
852#[unsafe(no_mangle)]
853pub unsafe extern "C" fn wasmtime_arrayref_len(
854 cx: WasmtimeStoreContextMut<'_>,
855 arrayref: Option<&wasmtime_arrayref_t>,
856 out: &mut MaybeUninit<u32>,
857) -> Option<Box<crate::wasmtime_error_t>> {
858 let arrayref = arrayref
859 .and_then(|a| a.as_wasmtime())
860 .expect("non-null arrayref required");
861 match arrayref.len(&cx) {
862 Ok(len) => {
863 crate::initialize(out, len);
864 None
865 }
866 Err(e) => Some(Box::new(e.into())),
867 }
868}
869
870#[unsafe(no_mangle)]
871pub unsafe extern "C" fn wasmtime_arrayref_get(
872 mut cx: WasmtimeStoreContextMut<'_>,
873 arrayref: Option<&wasmtime_arrayref_t>,
874 index: u32,
875 out: &mut MaybeUninit<crate::wasmtime_val_t>,
876) -> Option<Box<crate::wasmtime_error_t>> {
877 let arrayref = arrayref
878 .and_then(|a| a.as_wasmtime())
879 .expect("non-null arrayref required");
880 let mut scope = RootScope::new(&mut cx);
881 let rooted = arrayref.to_rooted(&mut scope);
882 match rooted.get(&mut scope, index) {
883 Ok(val) => {
884 let c_val = crate::wasmtime_val_t::from_val(&mut scope, val);
885 crate::initialize(out, c_val);
886 None
887 }
888 Err(e) => Some(Box::new(e.into())),
889 }
890}
891
892#[unsafe(no_mangle)]
893pub unsafe extern "C" fn wasmtime_arrayref_set(
894 mut cx: WasmtimeStoreContextMut<'_>,
895 arrayref: Option<&wasmtime_arrayref_t>,
896 index: u32,
897 val: &crate::wasmtime_val_t,
898) -> Option<Box<crate::wasmtime_error_t>> {
899 let arrayref = arrayref
900 .and_then(|a| a.as_wasmtime())
901 .expect("non-null arrayref required");
902 let mut scope = RootScope::new(&mut cx);
903 let rooted = arrayref.to_rooted(&mut scope);
904 let rust_val = val.to_val(&mut scope);
905 match rooted.set(&mut scope, index, rust_val) {
906 Ok(()) => None,
907 Err(e) => Some(Box::new(e.into())),
908 }
909}
910
911#[unsafe(no_mangle)]
912pub unsafe extern "C" fn wasmtime_eqref_is_array(
913 cx: WasmtimeStoreContextMut<'_>,
914 eqref: Option<&wasmtime_eqref_t>,
915) -> bool {
916 match eqref.and_then(|e| e.as_wasmtime()) {
917 Some(eqref) => eqref.is_array(&cx).expect("OwnedRooted always in scope"),
918 None => false,
919 }
920}
921
922#[unsafe(no_mangle)]
923pub unsafe extern "C" fn wasmtime_eqref_as_array(
924 mut cx: WasmtimeStoreContextMut<'_>,
925 eqref: Option<&wasmtime_eqref_t>,
926 out: &mut MaybeUninit<wasmtime_arrayref_t>,
927) -> bool {
928 if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
929 let mut scope = RootScope::new(&mut cx);
930 let rooted = eqref.to_rooted(&mut scope);
931 if let Ok(Some(arrayref)) = rooted.as_array(&scope) {
932 let owned = arrayref.to_owned_rooted(&mut scope).expect("just created");
933 crate::initialize(out, Some(owned).into());
934 return true;
935 }
936 }
937 crate::initialize(out, None::<OwnedRooted<ArrayRef>>.into());
938 false
939}
940
941#[unsafe(no_mangle)]
942pub unsafe extern "C" fn wasmtime_anyref_is_eqref(
943 cx: WasmtimeStoreContextMut<'_>,
944 anyref: Option<&wasmtime_anyref_t>,
945) -> bool {
946 match anyref.and_then(|a| a.as_wasmtime()) {
947 Some(anyref) => anyref.is_eqref(&cx).expect("OwnedRooted always in scope"),
948 None => false,
949 }
950}
951
952#[unsafe(no_mangle)]
953pub unsafe extern "C" fn wasmtime_anyref_as_eqref(
954 mut cx: WasmtimeStoreContextMut<'_>,
955 anyref: Option<&wasmtime_anyref_t>,
956 out: &mut MaybeUninit<wasmtime_eqref_t>,
957) -> bool {
958 if let Some(anyref) = anyref.and_then(|a| a.as_wasmtime()) {
959 let mut scope = RootScope::new(&mut cx);
960 let rooted = anyref.to_rooted(&mut scope);
961 if let Ok(Some(eqref)) = rooted.as_eqref(&mut scope) {
962 let owned = eqref.to_owned_rooted(&mut scope).expect("in scope");
963 crate::initialize(out, Some(owned).into());
964 return true;
965 }
966 }
967 crate::initialize(out, None::<OwnedRooted<EqRef>>.into());
968 false
969}
970
971#[unsafe(no_mangle)]
972pub unsafe extern "C" fn wasmtime_anyref_is_struct(
973 cx: WasmtimeStoreContextMut<'_>,
974 anyref: Option<&wasmtime_anyref_t>,
975) -> bool {
976 match anyref.and_then(|a| a.as_wasmtime()) {
977 Some(anyref) => anyref.is_struct(&cx).expect("OwnedRooted always in scope"),
978 None => false,
979 }
980}
981
982#[unsafe(no_mangle)]
983pub unsafe extern "C" fn wasmtime_anyref_as_struct(
984 mut cx: WasmtimeStoreContextMut<'_>,
985 anyref: Option<&wasmtime_anyref_t>,
986 out: &mut MaybeUninit<wasmtime_structref_t>,
987) -> bool {
988 if let Some(anyref) = anyref.and_then(|a| a.as_wasmtime()) {
989 let mut scope = RootScope::new(&mut cx);
990 let rooted = anyref.to_rooted(&mut scope);
991 if let Ok(Some(structref)) = rooted.as_struct(&scope) {
992 let owned = structref.to_owned_rooted(&mut scope).expect("in scope");
993 crate::initialize(out, Some(owned).into());
994 return true;
995 }
996 }
997 crate::initialize(out, None::<OwnedRooted<StructRef>>.into());
998 false
999}
1000
1001#[unsafe(no_mangle)]
1002pub unsafe extern "C" fn wasmtime_anyref_is_array(
1003 cx: WasmtimeStoreContextMut<'_>,
1004 anyref: Option<&wasmtime_anyref_t>,
1005) -> bool {
1006 match anyref.and_then(|a| a.as_wasmtime()) {
1007 Some(anyref) => anyref.is_array(&cx).expect("OwnedRooted always in scope"),
1008 None => false,
1009 }
1010}
1011
1012#[unsafe(no_mangle)]
1013pub unsafe extern "C" fn wasmtime_anyref_as_array(
1014 mut cx: WasmtimeStoreContextMut<'_>,
1015 anyref: Option<&wasmtime_anyref_t>,
1016 out: &mut MaybeUninit<wasmtime_arrayref_t>,
1017) -> bool {
1018 if let Some(anyref) = anyref.and_then(|a| a.as_wasmtime()) {
1019 let mut scope = RootScope::new(&mut cx);
1020 let rooted = anyref.to_rooted(&mut scope);
1021 if let Ok(Some(arrayref)) = rooted.as_array(&scope) {
1022 let owned = arrayref.to_owned_rooted(&mut scope).expect("in scope");
1023 crate::initialize(out, Some(owned).into());
1024 return true;
1025 }
1026 }
1027 crate::initialize(out, None::<OwnedRooted<ArrayRef>>.into());
1028 false
1029}