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