1 use crate::{
2     wasm_byte_vec_t, wasm_config_t, wasm_engine_t, wasmtime_component_type_t, wasmtime_error_t,
3 };
4 use std::ffi::{CStr, c_char};
5 use wasmtime::component::{Component, ComponentExportIndex};
6 use wasmtime::error::Context;
7 
8 #[unsafe(no_mangle)]
wasmtime_config_wasm_component_model_set(c: &mut wasm_config_t, enable: bool)9 pub extern "C" fn wasmtime_config_wasm_component_model_set(c: &mut wasm_config_t, enable: bool) {
10     c.config.wasm_component_model(enable);
11 }
12 
13 #[unsafe(no_mangle)]
wasmtime_config_wasm_component_model_map_set( c: &mut wasm_config_t, enable: bool, )14 pub extern "C" fn wasmtime_config_wasm_component_model_map_set(
15     c: &mut wasm_config_t,
16     enable: bool,
17 ) {
18     c.config.wasm_component_model_map(enable);
19 }
20 
21 #[derive(Clone)]
22 #[repr(transparent)]
23 pub struct wasmtime_component_t {
24     pub(crate) component: Component,
25 }
26 
27 #[unsafe(no_mangle)]
28 #[cfg(any(feature = "cranelift", feature = "winch"))]
wasmtime_component_new( engine: &wasm_engine_t, buf: *const u8, len: usize, component_out: &mut *mut wasmtime_component_t, ) -> Option<Box<wasmtime_error_t>>29 pub unsafe extern "C" fn wasmtime_component_new(
30     engine: &wasm_engine_t,
31     buf: *const u8,
32     len: usize,
33     component_out: &mut *mut wasmtime_component_t,
34 ) -> Option<Box<wasmtime_error_t>> {
35     let bytes = unsafe { crate::slice_from_raw_parts(buf, len) };
36     crate::handle_result(Component::new(&engine.engine, bytes), |component| {
37         *component_out = Box::into_raw(Box::new(wasmtime_component_t { component }));
38     })
39 }
40 
41 #[unsafe(no_mangle)]
42 #[cfg(any(feature = "cranelift", feature = "winch"))]
wasmtime_component_serialize( component: &wasmtime_component_t, ret: &mut wasm_byte_vec_t, ) -> Option<Box<wasmtime_error_t>>43 pub extern "C" fn wasmtime_component_serialize(
44     component: &wasmtime_component_t,
45     ret: &mut wasm_byte_vec_t,
46 ) -> Option<Box<wasmtime_error_t>> {
47     crate::handle_result(component.component.serialize(), |buffer| {
48         ret.set_buffer(buffer);
49     })
50 }
51 
52 #[unsafe(no_mangle)]
wasmtime_component_deserialize( engine: &wasm_engine_t, buf: *const u8, len: usize, component_out: &mut *mut wasmtime_component_t, ) -> Option<Box<wasmtime_error_t>>53 pub unsafe extern "C" fn wasmtime_component_deserialize(
54     engine: &wasm_engine_t,
55     buf: *const u8,
56     len: usize,
57     component_out: &mut *mut wasmtime_component_t,
58 ) -> Option<Box<wasmtime_error_t>> {
59     let binary = unsafe { crate::slice_from_raw_parts(buf, len) };
60     crate::handle_result(
61         unsafe { Component::deserialize(&engine.engine, binary) },
62         |component| {
63             *component_out = Box::into_raw(Box::new(wasmtime_component_t { component }));
64         },
65     )
66 }
67 
68 #[unsafe(no_mangle)]
wasmtime_component_deserialize_file( engine: &wasm_engine_t, path: *const c_char, component_out: &mut *mut wasmtime_component_t, ) -> Option<Box<wasmtime_error_t>>69 pub unsafe extern "C" fn wasmtime_component_deserialize_file(
70     engine: &wasm_engine_t,
71     path: *const c_char,
72     component_out: &mut *mut wasmtime_component_t,
73 ) -> Option<Box<wasmtime_error_t>> {
74     let path = unsafe { CStr::from_ptr(path) };
75     let result = path
76         .to_str()
77         .context("input path is not valid utf-8")
78         .and_then(|path| unsafe { Component::deserialize_file(&engine.engine, path) });
79     crate::handle_result(result, |component| {
80         *component_out = Box::into_raw(Box::new(wasmtime_component_t { component }));
81     })
82 }
83 
84 #[unsafe(no_mangle)]
wasmtime_component_type( component: &wasmtime_component_t, ) -> Box<wasmtime_component_type_t>85 pub extern "C" fn wasmtime_component_type(
86     component: &wasmtime_component_t,
87 ) -> Box<wasmtime_component_type_t> {
88     Box::new(component.component.component_type().into())
89 }
90 
91 #[unsafe(no_mangle)]
wasmtime_component_clone( component: &wasmtime_component_t, ) -> Box<wasmtime_component_t>92 pub extern "C" fn wasmtime_component_clone(
93     component: &wasmtime_component_t,
94 ) -> Box<wasmtime_component_t> {
95     Box::new(component.clone())
96 }
97 
98 #[unsafe(no_mangle)]
wasmtime_component_delete(_component: Box<wasmtime_component_t>)99 pub extern "C" fn wasmtime_component_delete(_component: Box<wasmtime_component_t>) {}
100 
101 #[repr(transparent)]
102 pub struct wasmtime_component_export_index_t {
103     pub(crate) export_index: ComponentExportIndex,
104 }
105 
106 #[unsafe(no_mangle)]
wasmtime_component_get_export_index( component: &wasmtime_component_t, instance_export_index: *const wasmtime_component_export_index_t, name: *const u8, name_len: usize, ) -> Option<Box<wasmtime_component_export_index_t>>107 pub unsafe extern "C" fn wasmtime_component_get_export_index(
108     component: &wasmtime_component_t,
109     instance_export_index: *const wasmtime_component_export_index_t,
110     name: *const u8,
111     name_len: usize,
112 ) -> Option<Box<wasmtime_component_export_index_t>> {
113     let name = unsafe { std::slice::from_raw_parts(name, name_len) };
114     let Ok(name) = std::str::from_utf8(name) else {
115         return None;
116     };
117 
118     let instance_export_index = if instance_export_index.is_null() {
119         None
120     } else {
121         Some((*instance_export_index).export_index)
122     };
123 
124     component
125         .component
126         .get_export_index(instance_export_index.as_ref(), &name)
127         .map(|export_index| Box::new(wasmtime_component_export_index_t { export_index }))
128 }
129 
130 #[unsafe(no_mangle)]
wasmtime_component_export_index_clone( export_index: &wasmtime_component_export_index_t, ) -> Box<wasmtime_component_export_index_t>131 pub extern "C" fn wasmtime_component_export_index_clone(
132     export_index: &wasmtime_component_export_index_t,
133 ) -> Box<wasmtime_component_export_index_t> {
134     Box::new(wasmtime_component_export_index_t {
135         export_index: export_index.export_index,
136     })
137 }
138 
139 #[unsafe(no_mangle)]
wasmtime_component_export_index_delete( _export_index: Box<wasmtime_component_export_index_t>, )140 pub extern "C" fn wasmtime_component_export_index_delete(
141     _export_index: Box<wasmtime_component_export_index_t>,
142 ) {
143 }
144