1use crate::{WasmtimeStoreContextMut, abort};
2use std::mem::{ManuallyDrop, MaybeUninit};
3use std::{num::NonZeroU64, os::raw::c_void, ptr};
4use wasmtime::{
5 AnyRef, EqRef, ExnRef, ExternRef, FieldType, I31, Mutability, OwnedRooted, Ref, RootScope,
6 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
285#[unsafe(no_mangle)]
286pub unsafe extern "C" fn wasmtime_anyref_clone(
287 anyref: Option<&wasmtime_anyref_t>,
288 out: &mut MaybeUninit<wasmtime_anyref_t>,
289) {
290 let anyref = anyref.and_then(|a| a.as_wasmtime());
291 crate::initialize(out, anyref.into());
292}
293
294#[unsafe(no_mangle)]
295pub unsafe extern "C" fn wasmtime_anyref_unroot(val: Option<&mut ManuallyDrop<wasmtime_anyref_t>>) {
296 if let Some(val) = val {
297 unsafe {
298 ManuallyDrop::drop(val);
299 }
300 }
301}
302
303#[unsafe(no_mangle)]
304pub unsafe extern "C" fn wasmtime_anyref_to_raw(
305 cx: WasmtimeStoreContextMut<'_>,
306 val: Option<&wasmtime_anyref_t>,
307) -> u32 {
308 val.and_then(|v| v.as_wasmtime())
309 .and_then(|e| e.to_raw(cx).ok())
310 .unwrap_or_default()
311}
312
313#[unsafe(no_mangle)]
314pub unsafe extern "C" fn wasmtime_anyref_from_raw(
315 cx: WasmtimeStoreContextMut<'_>,
316 raw: u32,
317 val: &mut MaybeUninit<wasmtime_anyref_t>,
318) {
319 let mut scope = RootScope::new(cx);
320 let anyref =
321 AnyRef::from_raw(&mut scope, raw).map(|a| a.to_owned_rooted(&mut scope).expect("in scope"));
322 crate::initialize(val, anyref.into());
323}
324
325#[unsafe(no_mangle)]
326pub extern "C" fn wasmtime_anyref_from_i31(
327 cx: WasmtimeStoreContextMut<'_>,
328 val: u32,
329 out: &mut MaybeUninit<wasmtime_anyref_t>,
330) {
331 let mut scope = RootScope::new(cx);
332 let anyref = AnyRef::from_i31(&mut scope, I31::wrapping_u32(val));
333 let anyref = anyref.to_owned_rooted(&mut scope).expect("in scope");
334 crate::initialize(out, Some(anyref).into())
335}
336
337#[unsafe(no_mangle)]
338pub unsafe extern "C" fn wasmtime_anyref_is_i31(
339 cx: WasmtimeStoreContextMut<'_>,
340 anyref: Option<&wasmtime_anyref_t>,
341) -> bool {
342 match anyref.and_then(|a| a.as_wasmtime()) {
343 Some(anyref) => anyref.is_i31(&cx).expect("OwnedRooted always in scope"),
344 None => false,
345 }
346}
347
348#[unsafe(no_mangle)]
349pub unsafe extern "C" fn wasmtime_anyref_i31_get_u(
350 cx: WasmtimeStoreContextMut<'_>,
351 anyref: Option<&wasmtime_anyref_t>,
352 dst: &mut MaybeUninit<u32>,
353) -> bool {
354 match anyref.and_then(|a| a.as_wasmtime()) {
355 Some(anyref) if anyref.is_i31(&cx).expect("OwnedRooted always in scope") => {
356 let val = anyref
357 .unwrap_i31(&cx)
358 .expect("OwnedRooted always in scope")
359 .get_u32();
360 crate::initialize(dst, val);
361 true
362 }
363 _ => false,
364 }
365}
366
367#[unsafe(no_mangle)]
368pub unsafe extern "C" fn wasmtime_anyref_i31_get_s(
369 cx: WasmtimeStoreContextMut<'_>,
370 anyref: Option<&wasmtime_anyref_t>,
371 dst: &mut MaybeUninit<i32>,
372) -> bool {
373 match anyref.and_then(|a| a.as_wasmtime()) {
374 Some(anyref) if anyref.is_i31(&cx).expect("OwnedRooted always in scope") => {
375 let val = anyref
376 .unwrap_i31(&cx)
377 .expect("OwnedRooted always in scope")
378 .get_i32();
379 crate::initialize(dst, val);
380 true
381 }
382 _ => false,
383 }
384}
385
386#[unsafe(no_mangle)]
387pub extern "C" fn wasmtime_externref_new(
388 cx: WasmtimeStoreContextMut<'_>,
389 data: *mut c_void,
390 finalizer: Option<extern "C" fn(*mut c_void)>,
391 out: &mut MaybeUninit<wasmtime_externref_t>,
392) -> bool {
393 let mut scope = RootScope::new(cx);
394 let e = match ExternRef::new(&mut scope, crate::ForeignData { data, finalizer }) {
395 Ok(e) => e,
396 Err(_) => return false,
397 };
398 let e = e.to_owned_rooted(&mut scope).expect("in scope");
399 crate::initialize(out, Some(e).into());
400 true
401}
402
403#[unsafe(no_mangle)]
404pub unsafe extern "C" fn wasmtime_externref_data(
405 cx: WasmtimeStoreContextMut<'_>,
406 externref: Option<&wasmtime_externref_t>,
407) -> *mut c_void {
408 externref
409 .and_then(|e| e.as_wasmtime())
410 .and_then(|e| {
411 let data = e.data(cx).ok()??;
412 Some(data.downcast_ref::<crate::ForeignData>().unwrap().data)
413 })
414 .unwrap_or(ptr::null_mut())
415}
416
417#[unsafe(no_mangle)]
418pub unsafe extern "C" fn wasmtime_externref_clone(
419 externref: Option<&wasmtime_externref_t>,
420 out: &mut MaybeUninit<wasmtime_externref_t>,
421) {
422 let externref = externref.and_then(|e| e.as_wasmtime());
423 crate::initialize(out, externref.into());
424}
425
426#[unsafe(no_mangle)]
427pub unsafe extern "C" fn wasmtime_externref_unroot(
428 val: Option<&mut ManuallyDrop<wasmtime_externref_t>>,
429) {
430 if let Some(val) = val {
431 unsafe {
432 ManuallyDrop::drop(val);
433 }
434 }
435}
436
437#[unsafe(no_mangle)]
438pub unsafe extern "C" fn wasmtime_externref_to_raw(
439 cx: WasmtimeStoreContextMut<'_>,
440 val: Option<&wasmtime_externref_t>,
441) -> u32 {
442 val.and_then(|e| e.as_wasmtime())
443 .and_then(|e| e.to_raw(cx).ok())
444 .unwrap_or_default()
445}
446
447#[unsafe(no_mangle)]
448pub unsafe extern "C" fn wasmtime_externref_from_raw(
449 cx: WasmtimeStoreContextMut<'_>,
450 raw: u32,
451 val: &mut MaybeUninit<wasmtime_externref_t>,
452) {
453 let mut scope = RootScope::new(cx);
454 let rooted = ExternRef::from_raw(&mut scope, raw)
455 .map(|e| e.to_owned_rooted(&mut scope).expect("in scope"));
456 crate::initialize(val, rooted.into());
457}
458
459#[unsafe(no_mangle)]
460pub unsafe extern "C" fn wasmtime_exnref_clone(
461 exnref: Option<&wasmtime_exnref_t>,
462 out: &mut MaybeUninit<wasmtime_exnref_t>,
463) {
464 let exnref = exnref.and_then(|e| e.as_wasmtime());
465 crate::initialize(out, exnref.into());
466}
467
468#[unsafe(no_mangle)]
469pub unsafe extern "C" fn wasmtime_exnref_unroot(val: Option<&mut ManuallyDrop<wasmtime_exnref_t>>) {
470 if let Some(val) = val {
471 unsafe {
472 ManuallyDrop::drop(val);
473 }
474 }
475}
476
477#[unsafe(no_mangle)]
478pub unsafe extern "C" fn wasmtime_eqref_clone(
479 eqref: Option<&wasmtime_eqref_t>,
480 out: &mut MaybeUninit<wasmtime_eqref_t>,
481) {
482 let eqref = eqref.and_then(|e| e.as_wasmtime());
483 crate::initialize(out, eqref.into());
484}
485
486#[unsafe(no_mangle)]
487pub unsafe extern "C" fn wasmtime_eqref_unroot(val: Option<&mut ManuallyDrop<wasmtime_eqref_t>>) {
488 if let Some(val) = val {
489 unsafe {
490 ManuallyDrop::drop(val);
491 }
492 }
493}
494
495#[unsafe(no_mangle)]
496pub unsafe extern "C" fn wasmtime_eqref_to_anyref(
497 eqref: Option<&wasmtime_eqref_t>,
498 out: &mut MaybeUninit<wasmtime_anyref_t>,
499) {
500 let anyref = eqref.and_then(|e| e.as_wasmtime()).map(|e| e.to_anyref());
501 crate::initialize(out, anyref.into());
502}
503
504#[unsafe(no_mangle)]
505pub extern "C" fn wasmtime_eqref_from_i31(
506 cx: WasmtimeStoreContextMut<'_>,
507 val: u32,
508 out: &mut MaybeUninit<wasmtime_eqref_t>,
509) {
510 let mut scope = RootScope::new(cx);
511 let eqref = EqRef::from_i31(&mut scope, I31::wrapping_u32(val));
512 let eqref = eqref.to_owned_rooted(&mut scope).expect("in scope");
513 crate::initialize(out, Some(eqref).into())
514}
515
516#[unsafe(no_mangle)]
517pub unsafe extern "C" fn wasmtime_eqref_is_i31(
518 cx: WasmtimeStoreContextMut<'_>,
519 eqref: Option<&wasmtime_eqref_t>,
520) -> bool {
521 match eqref.and_then(|e| e.as_wasmtime()) {
522 Some(eqref) => eqref.is_i31(&cx).expect("OwnedRooted always in scope"),
523 None => false,
524 }
525}
526
527#[unsafe(no_mangle)]
528pub unsafe extern "C" fn wasmtime_eqref_i31_get_u(
529 cx: WasmtimeStoreContextMut<'_>,
530 eqref: Option<&wasmtime_eqref_t>,
531 dst: &mut MaybeUninit<u32>,
532) -> bool {
533 let mut scope = RootScope::new(cx);
534 if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
535 if let Some(val) = eqref.as_i31(&mut scope).expect("in scope") {
536 crate::initialize(dst, val.get_u32());
537 return true;
538 }
539 }
540 false
541}
542
543#[unsafe(no_mangle)]
544pub unsafe extern "C" fn wasmtime_eqref_i31_get_s(
545 cx: WasmtimeStoreContextMut<'_>,
546 eqref: Option<&wasmtime_eqref_t>,
547 dst: &mut MaybeUninit<i32>,
548) -> bool {
549 let mut scope = RootScope::new(cx);
550 if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
551 if let Some(val) = eqref.as_i31(&mut scope).expect("in scope") {
552 crate::initialize(dst, val.get_i32());
553 return true;
554 }
555 }
556 false
557}
558
559pub type wasmtime_storage_kind_t = u8;
560pub const WASMTIME_STORAGE_KIND_I8: wasmtime_storage_kind_t = 9;
561pub const WASMTIME_STORAGE_KIND_I16: wasmtime_storage_kind_t = 10;
562
563#[repr(C)]
564pub struct wasmtime_field_type_t {
565 pub kind: wasmtime_storage_kind_t,
566 pub mutable_: bool,
567}
568
569fn field_type_from_c(ft: &wasmtime_field_type_t) -> FieldType {
570 let mutability = if ft.mutable_ {
571 Mutability::Var
572 } else {
573 Mutability::Const
574 };
575 let storage = match ft.kind {
576 WASMTIME_STORAGE_KIND_I8 => StorageType::I8,
577 WASMTIME_STORAGE_KIND_I16 => StorageType::I16,
578 crate::WASMTIME_I32 => StorageType::ValType(ValType::I32),
579 crate::WASMTIME_I64 => StorageType::ValType(ValType::I64),
580 crate::WASMTIME_F32 => StorageType::ValType(ValType::F32),
581 crate::WASMTIME_F64 => StorageType::ValType(ValType::F64),
582 crate::WASMTIME_V128 => StorageType::ValType(ValType::V128),
583 crate::WASMTIME_FUNCREF => StorageType::ValType(ValType::FUNCREF),
584 crate::WASMTIME_EXTERNREF => StorageType::ValType(ValType::EXTERNREF),
585 crate::WASMTIME_ANYREF => StorageType::ValType(ValType::ANYREF),
586 crate::WASMTIME_EXNREF => StorageType::ValType(ValType::EXNREF),
587 other => panic!("unknown wasmtime_storage_kind_t: {other}"),
588 };
589 FieldType::new(mutability, storage)
590}
591
592#[unsafe(no_mangle)]
593pub extern "C" fn wasmtime_struct_type_new(
594 engine: &crate::wasm_engine_t,
595 fields: *const wasmtime_field_type_t,
596 nfields: usize,
597) -> Box<wasmtime_struct_type_t> {
598 let fields = if nfields == 0 {
599 &[]
600 } else {
601 unsafe { std::slice::from_raw_parts(fields, nfields) }
602 };
603 let field_types: Vec<FieldType> = fields.iter().map(field_type_from_c).collect();
604 let ty = StructType::new(&engine.engine, field_types).expect("failed to create struct type");
605 Box::new(wasmtime_struct_type_t { ty })
606}
607
608#[unsafe(no_mangle)]
609pub extern "C" fn wasmtime_struct_ref_pre_new(
610 cx: WasmtimeStoreContextMut<'_>,
611 ty: &wasmtime_struct_type_t,
612) -> Box<wasmtime_struct_ref_pre_t> {
613 let pre = StructRefPre::new(cx, ty.ty.clone());
614 Box::new(wasmtime_struct_ref_pre_t { pre })
615}
616
617#[unsafe(no_mangle)]
618pub unsafe extern "C" fn wasmtime_structref_new(
619 mut cx: WasmtimeStoreContextMut<'_>,
620 pre: &wasmtime_struct_ref_pre_t,
621 fields: *const crate::wasmtime_val_t,
622 nfields: usize,
623 out: &mut MaybeUninit<wasmtime_structref_t>,
624) -> Option<Box<crate::wasmtime_error_t>> {
625 let c_fields = if nfields == 0 {
626 &[]
627 } else {
628 std::slice::from_raw_parts(fields, nfields)
629 };
630 let mut scope = RootScope::new(&mut cx);
631 let vals: Vec<Val> = c_fields.iter().map(|v| v.to_val(&mut scope)).collect();
632 match StructRef::new(&mut scope, &pre.pre, &vals) {
633 Ok(structref) => {
634 let owned = structref
635 .to_owned_rooted(&mut scope)
636 .expect("just allocated");
637 crate::initialize(out, Some(owned).into());
638 None
639 }
640 Err(e) => {
641 crate::initialize(out, None::<OwnedRooted<StructRef>>.into());
642 Some(Box::new(e.into()))
643 }
644 }
645}
646
647#[unsafe(no_mangle)]
648pub unsafe extern "C" fn wasmtime_structref_clone(
649 structref: Option<&wasmtime_structref_t>,
650 out: &mut MaybeUninit<wasmtime_structref_t>,
651) {
652 let structref = structref.and_then(|s| s.as_wasmtime());
653 crate::initialize(out, structref.into());
654}
655
656#[unsafe(no_mangle)]
657pub unsafe extern "C" fn wasmtime_structref_unroot(
658 structref: Option<&mut ManuallyDrop<wasmtime_structref_t>>,
659) {
660 if let Some(structref) = structref {
661 ManuallyDrop::drop(structref);
662 }
663}
664
665#[unsafe(no_mangle)]
666pub unsafe extern "C" fn wasmtime_structref_to_anyref(
667 structref: Option<&wasmtime_structref_t>,
668 out: &mut MaybeUninit<wasmtime_anyref_t>,
669) {
670 let anyref = structref
671 .and_then(|s| s.as_wasmtime())
672 .map(|s| s.to_anyref());
673 crate::initialize(out, anyref.into());
674}
675
676#[unsafe(no_mangle)]
677pub unsafe extern "C" fn wasmtime_structref_to_eqref(
678 structref: Option<&wasmtime_structref_t>,
679 out: &mut MaybeUninit<wasmtime_eqref_t>,
680) {
681 let eqref = structref
682 .and_then(|s| s.as_wasmtime())
683 .map(|s| s.to_eqref());
684 crate::initialize(out, eqref.into());
685}
686
687#[unsafe(no_mangle)]
688pub unsafe extern "C" fn wasmtime_structref_field(
689 mut cx: WasmtimeStoreContextMut<'_>,
690 structref: Option<&wasmtime_structref_t>,
691 index: usize,
692 out: &mut MaybeUninit<crate::wasmtime_val_t>,
693) -> Option<Box<crate::wasmtime_error_t>> {
694 let structref = structref
695 .and_then(|s| s.as_wasmtime())
696 .expect("non-null structref required");
697 let mut scope = RootScope::new(&mut cx);
698 let rooted = structref.to_rooted(&mut scope);
699 match rooted.field(&mut scope, index) {
700 Ok(val) => {
701 let c_val = crate::wasmtime_val_t::from_val(&mut scope, val);
702 crate::initialize(out, c_val);
703 None
704 }
705 Err(e) => Some(Box::new(e.into())),
706 }
707}
708
709#[unsafe(no_mangle)]
710pub unsafe extern "C" fn wasmtime_structref_set_field(
711 mut cx: WasmtimeStoreContextMut<'_>,
712 structref: Option<&wasmtime_structref_t>,
713 index: usize,
714 val: &crate::wasmtime_val_t,
715) -> Option<Box<crate::wasmtime_error_t>> {
716 let structref = structref
717 .and_then(|s| s.as_wasmtime())
718 .expect("non-null structref required");
719 let mut scope = RootScope::new(&mut cx);
720 let rooted = structref.to_rooted(&mut scope);
721 let rust_val = val.to_val(&mut scope);
722 match rooted.set_field(&mut scope, index, rust_val) {
723 Ok(()) => None,
724 Err(e) => Some(Box::new(e.into())),
725 }
726}
727
728#[unsafe(no_mangle)]
729pub unsafe extern "C" fn wasmtime_eqref_is_struct(
730 cx: WasmtimeStoreContextMut<'_>,
731 eqref: Option<&wasmtime_eqref_t>,
732) -> bool {
733 match eqref.and_then(|e| e.as_wasmtime()) {
734 Some(eqref) => eqref.is_struct(&cx).expect("OwnedRooted always in scope"),
735 None => false,
736 }
737}
738
739#[unsafe(no_mangle)]
740pub unsafe extern "C" fn wasmtime_eqref_as_struct(
741 mut cx: WasmtimeStoreContextMut<'_>,
742 eqref: Option<&wasmtime_eqref_t>,
743 out: &mut MaybeUninit<wasmtime_structref_t>,
744) -> bool {
745 if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
746 let mut scope = RootScope::new(&mut cx);
747 let rooted = eqref.to_rooted(&mut scope);
748 if let Ok(Some(structref)) = rooted.as_struct(&scope) {
749 let owned = structref.to_owned_rooted(&mut scope).expect("in scope");
750 crate::initialize(out, Some(owned).into());
751 return true;
752 }
753 }
754 crate::initialize(out, None::<OwnedRooted<StructRef>>.into());
755 false
756}