1 use crate::{
2 WasmtimeStoreContextMut, WasmtimeStoreData, wasm_engine_t, wasmtime_component_func_type_t,
3 wasmtime_component_resource_type_t, wasmtime_error_t, wasmtime_module_t,
4 };
5 use std::ffi::c_void;
6 use wasmtime::component::{Instance, Linker, LinkerInstance, Val};
7
8 use super::{wasmtime_component_t, wasmtime_component_val_t};
9
10 #[repr(transparent)]
11 pub struct wasmtime_component_linker_t {
12 pub(crate) linker: Linker<WasmtimeStoreData>,
13 }
14
15 #[repr(transparent)]
16 pub struct wasmtime_component_linker_instance_t<'a> {
17 pub(crate) linker_instance: LinkerInstance<'a, WasmtimeStoreData>,
18 }
19
20 #[unsafe(no_mangle)]
wasmtime_component_linker_new( engine: &wasm_engine_t, ) -> Box<wasmtime_component_linker_t>21 pub extern "C" fn wasmtime_component_linker_new(
22 engine: &wasm_engine_t,
23 ) -> Box<wasmtime_component_linker_t> {
24 Box::new(wasmtime_component_linker_t {
25 linker: Linker::new(&engine.engine),
26 })
27 }
28
29 #[unsafe(no_mangle)]
wasmtime_component_linker_allow_shadowing( linker: &mut wasmtime_component_linker_t, allow: bool, )30 pub extern "C" fn wasmtime_component_linker_allow_shadowing(
31 linker: &mut wasmtime_component_linker_t,
32 allow: bool,
33 ) {
34 linker.linker.allow_shadowing(allow);
35 }
36
37 #[unsafe(no_mangle)]
wasmtime_component_linker_root( linker: &mut wasmtime_component_linker_t, ) -> Box<wasmtime_component_linker_instance_t<'_>>38 pub extern "C" fn wasmtime_component_linker_root(
39 linker: &mut wasmtime_component_linker_t,
40 ) -> Box<wasmtime_component_linker_instance_t<'_>> {
41 Box::new(wasmtime_component_linker_instance_t {
42 linker_instance: linker.linker.root(),
43 })
44 }
45
46 #[unsafe(no_mangle)]
wasmtime_component_linker_instantiate( linker: &wasmtime_component_linker_t, context: WasmtimeStoreContextMut<'_>, component: &wasmtime_component_t, instance_out: &mut Instance, ) -> Option<Box<wasmtime_error_t>>47 pub extern "C" fn wasmtime_component_linker_instantiate(
48 linker: &wasmtime_component_linker_t,
49 context: WasmtimeStoreContextMut<'_>,
50 component: &wasmtime_component_t,
51 instance_out: &mut Instance,
52 ) -> Option<Box<wasmtime_error_t>> {
53 let result = linker.linker.instantiate(context, &component.component);
54 crate::handle_result(result, |instance| *instance_out = instance)
55 }
56
57 #[unsafe(no_mangle)]
wasmtime_component_linker_delete(_linker: Box<wasmtime_component_linker_t>)58 pub extern "C" fn wasmtime_component_linker_delete(_linker: Box<wasmtime_component_linker_t>) {}
59
60 #[unsafe(no_mangle)]
wasmtime_component_linker_instance_add_instance<'a>( linker_instance: &'a mut wasmtime_component_linker_instance_t<'a>, name: *const u8, name_len: usize, linker_instance_out: &mut *mut wasmtime_component_linker_instance_t<'a>, ) -> Option<Box<wasmtime_error_t>>61 pub unsafe extern "C" fn wasmtime_component_linker_instance_add_instance<'a>(
62 linker_instance: &'a mut wasmtime_component_linker_instance_t<'a>,
63 name: *const u8,
64 name_len: usize,
65 linker_instance_out: &mut *mut wasmtime_component_linker_instance_t<'a>,
66 ) -> Option<Box<wasmtime_error_t>> {
67 let name = unsafe { std::slice::from_raw_parts(name, name_len) };
68 let Ok(name) = std::str::from_utf8(name) else {
69 return crate::bad_utf8();
70 };
71
72 let result = linker_instance.linker_instance.instance(&name);
73 crate::handle_result(result, |linker_instance| {
74 *linker_instance_out = Box::into_raw(Box::new(wasmtime_component_linker_instance_t {
75 linker_instance,
76 }));
77 })
78 }
79
80 #[unsafe(no_mangle)]
wasmtime_component_linker_instance_add_module( linker_instance: &mut wasmtime_component_linker_instance_t, name: *const u8, name_len: usize, module: &wasmtime_module_t, ) -> Option<Box<wasmtime_error_t>>81 pub unsafe extern "C" fn wasmtime_component_linker_instance_add_module(
82 linker_instance: &mut wasmtime_component_linker_instance_t,
83 name: *const u8,
84 name_len: usize,
85 module: &wasmtime_module_t,
86 ) -> Option<Box<wasmtime_error_t>> {
87 let name = unsafe { std::slice::from_raw_parts(name, name_len) };
88 let Ok(name) = std::str::from_utf8(name) else {
89 return crate::bad_utf8();
90 };
91
92 let result = linker_instance
93 .linker_instance
94 .module(&name, &module.module);
95
96 crate::handle_result(result, |_| ())
97 }
98
99 pub type wasmtime_component_func_callback_t = extern "C" fn(
100 *mut c_void,
101 WasmtimeStoreContextMut<'_>,
102 &wasmtime_component_func_type_t,
103 *mut wasmtime_component_val_t,
104 usize,
105 *mut wasmtime_component_val_t,
106 usize,
107 ) -> Option<Box<wasmtime_error_t>>;
108
109 #[unsafe(no_mangle)]
wasmtime_component_linker_instance_add_func( linker_instance: &mut wasmtime_component_linker_instance_t, name: *const u8, name_len: usize, callback: wasmtime_component_func_callback_t, data: *mut c_void, finalizer: Option<extern "C" fn(*mut c_void)>, ) -> Option<Box<wasmtime_error_t>>110 pub unsafe extern "C" fn wasmtime_component_linker_instance_add_func(
111 linker_instance: &mut wasmtime_component_linker_instance_t,
112 name: *const u8,
113 name_len: usize,
114 callback: wasmtime_component_func_callback_t,
115 data: *mut c_void,
116 finalizer: Option<extern "C" fn(*mut c_void)>,
117 ) -> Option<Box<wasmtime_error_t>> {
118 let name = unsafe { std::slice::from_raw_parts(name, name_len) };
119 let Ok(name) = std::str::from_utf8(name) else {
120 return crate::bad_utf8();
121 };
122
123 let foreign = crate::ForeignData { data, finalizer };
124
125 let result = linker_instance
126 .linker_instance
127 .func_new(&name, move |ctx, ty, args, rets| {
128 let _ = &foreign;
129
130 let mut args = args
131 .iter()
132 .map(|x| wasmtime_component_val_t::from(x))
133 .collect::<Vec<_>>();
134
135 let mut c_rets = vec![wasmtime_component_val_t::Bool(false); rets.len()];
136
137 let res = callback(
138 foreign.data,
139 ctx,
140 &ty.into(),
141 args.as_mut_ptr(),
142 args.len(),
143 c_rets.as_mut_ptr(),
144 c_rets.len(),
145 );
146
147 if let Some(res) = res {
148 return Err((*res).into());
149 }
150
151 for (rust_val, c_val) in std::iter::zip(rets, c_rets) {
152 *rust_val = Val::from(&c_val);
153 }
154
155 Ok(())
156 });
157
158 crate::handle_result(result, |_| ())
159 }
160
161 #[unsafe(no_mangle)]
162 #[cfg(feature = "wasi")]
wasmtime_component_linker_add_wasip2( linker: &mut wasmtime_component_linker_t, ) -> Option<Box<wasmtime_error_t>>163 pub unsafe extern "C" fn wasmtime_component_linker_add_wasip2(
164 linker: &mut wasmtime_component_linker_t,
165 ) -> Option<Box<wasmtime_error_t>> {
166 let result = wasmtime_wasi::p2::add_to_linker_sync(&mut linker.linker);
167 crate::handle_result(result, |_| ())
168 }
169
170 #[unsafe(no_mangle)]
171 #[cfg(feature = "wasi-http")]
wasmtime_component_linker_add_wasi_http( linker: &mut wasmtime_component_linker_t, ) -> Option<Box<wasmtime_error_t>>172 pub unsafe extern "C" fn wasmtime_component_linker_add_wasi_http(
173 linker: &mut wasmtime_component_linker_t,
174 ) -> Option<Box<wasmtime_error_t>> {
175 let result = wasmtime_wasi_http::p2::add_only_http_to_linker_sync(&mut linker.linker);
176 crate::handle_result(result, |_| ())
177 }
178
179 #[unsafe(no_mangle)]
wasmtime_component_linker_define_unknown_imports_as_traps( linker: &mut wasmtime_component_linker_t, component: &wasmtime_component_t, ) -> Option<Box<wasmtime_error_t>>180 pub unsafe extern "C" fn wasmtime_component_linker_define_unknown_imports_as_traps(
181 linker: &mut wasmtime_component_linker_t,
182 component: &wasmtime_component_t,
183 ) -> Option<Box<wasmtime_error_t>> {
184 let result = linker
185 .linker
186 .define_unknown_imports_as_traps(&component.component);
187 crate::handle_result(result, |_| ())
188 }
189
190 pub type wasmtime_component_resource_destructor_t =
191 extern "C" fn(*mut c_void, WasmtimeStoreContextMut<'_>, u32) -> Option<Box<wasmtime_error_t>>;
192
193 #[unsafe(no_mangle)]
wasmtime_component_linker_instance_add_resource( linker_instance: &mut wasmtime_component_linker_instance_t, name: *const u8, name_len: usize, ty: &wasmtime_component_resource_type_t, callback: wasmtime_component_resource_destructor_t, data: *mut c_void, finalizer: Option<extern "C" fn(*mut c_void)>, ) -> Option<Box<wasmtime_error_t>>194 pub unsafe extern "C" fn wasmtime_component_linker_instance_add_resource(
195 linker_instance: &mut wasmtime_component_linker_instance_t,
196 name: *const u8,
197 name_len: usize,
198 ty: &wasmtime_component_resource_type_t,
199 callback: wasmtime_component_resource_destructor_t,
200 data: *mut c_void,
201 finalizer: Option<extern "C" fn(*mut c_void)>,
202 ) -> Option<Box<wasmtime_error_t>> {
203 let name = unsafe { std::slice::from_raw_parts(name, name_len) };
204 let Ok(name) = std::str::from_utf8(name) else {
205 return crate::bad_utf8();
206 };
207
208 let foreign = crate::ForeignData { data, finalizer };
209
210 let result = linker_instance
211 .linker_instance
212 .resource(name, ty.ty, move |ctx, rep| {
213 let _ = &foreign;
214 if let Some(res) = callback(foreign.data, ctx, rep) {
215 return Err((*res).into());
216 }
217 Ok(())
218 });
219
220 crate::handle_result(result, |_| ())
221 }
222
223 #[unsafe(no_mangle)]
wasmtime_component_linker_instance_delete( _linker_instance: Box<wasmtime_component_linker_instance_t>, )224 pub unsafe extern "C" fn wasmtime_component_linker_instance_delete(
225 _linker_instance: Box<wasmtime_component_linker_instance_t>,
226 ) {
227 }
228