Skip to main content

wasmtime_c_api/component/
component.rs

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