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#[derive(Clone)]
22#[repr(transparent)]
23pub struct wasmtime_component_t {
24    pub(crate) component: Component,
25}
26
27#[unsafe(no_mangle)]
28#[cfg(any(feature = "cranelift", feature = "winch"))]
29pub 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"))]
43pub 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)]
53pub 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)]
69pub 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)]
85pub 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)]
92pub 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)]
99pub extern "C" fn wasmtime_component_delete(_component: Box<wasmtime_component_t>) {}
100
101#[repr(transparent)]
102pub struct wasmtime_component_export_index_t {
103    pub(crate) export_index: ComponentExportIndex,
104}
105
106#[unsafe(no_mangle)]
107pub 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)]
131pub 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)]
140pub extern "C" fn wasmtime_component_export_index_delete(
141    _export_index: Box<wasmtime_component_export_index_t>,
142) {
143}