From f14d4579ceb535552e18df7c905a9bffae8eafd3 Mon Sep 17 00:00:00 2001 From: Jean-Jacques Lafay Date: Fri, 13 Dec 2024 17:51:43 +0100 Subject: [PATCH] Fix CI --- crates/c-api/include/wasmtime/component.h | 440 +++++++++++++--------- crates/c-api/src/lib.rs | 3 +- examples/CMakeLists.txt | 3 + examples/component/main.c | 115 +++--- examples/component/main.rs | 18 +- 5 files changed, 344 insertions(+), 235 deletions(-) diff --git a/crates/c-api/include/wasmtime/component.h b/crates/c-api/include/wasmtime/component.h index 4daf02a3b77f..3d8922503fc3 100644 --- a/crates/c-api/include/wasmtime/component.h +++ b/crates/c-api/include/wasmtime/component.h @@ -26,60 +26,65 @@ extern "C" { WASMTIME_CONFIG_PROP(void, component_model, bool) /** - * \brief The tag part of #wasmtime_component_val_t or #wasmtime_component_type_t + * \brief The tag part of #wasmtime_component_val_t or + * #wasmtime_component_type_t * * Specifies what variant is populated in #wasmtime_component_val_payload_t * or #wasmtime_component_type_payload_t. + * + * Note that resources are currently not supported. */ typedef uint8_t wasmtime_component_kind_t; -/// \brief Value of #wasmtime_component_kind_t indicating a boolean +/// Value of #wasmtime_component_kind_t indicating a boolean #define WASMTIME_COMPONENT_KIND_BOOL 0 -/// \brief Value of #wasmtime_component_kind_t indicating a signed 8-bit integer +/// Value of #wasmtime_component_kind_t indicating a signed 8-bit integer #define WASMTIME_COMPONENT_KIND_S8 1 -/// \brief Value of #wasmtime_component_kind_t indicating an unsigned 8-bit integer +/// Value of #wasmtime_component_kind_t indicating an unsigned 8-bit integer #define WASMTIME_COMPONENT_KIND_U8 2 -/// \brief Value of #wasmtime_component_kind_t indicating a signed 16-bit integer +/// Value of #wasmtime_component_kind_t indicating a signed 16-bit integer #define WASMTIME_COMPONENT_KIND_S16 3 -/// \brief Value of #wasmtime_component_kind_t indicating an unsigned 16-bit integer +/// Value of #wasmtime_component_kind_t indicating an unsigned 16-bit integer #define WASMTIME_COMPONENT_KIND_U16 4 -/// \brief Value of #wasmtime_component_kind_t indicating a signed 32-bit integer +/// Value of #wasmtime_component_kind_t indicating a signed 32-bit integer #define WASMTIME_COMPONENT_KIND_S32 5 -/// \brief Value of #wasmtime_component_kind_t indicating an unsigned 32-bit integer +/// Value of #wasmtime_component_kind_t indicating an unsigned 32-bit integer #define WASMTIME_COMPONENT_KIND_U32 6 -/// \brief Value of #wasmtime_component_kind_t indicating a signed 64-bit integer +/// Value of #wasmtime_component_kind_t indicating a signed 64-bit integer #define WASMTIME_COMPONENT_KIND_S64 7 -/// \brief Value of #wasmtime_component_kind_t indicating an unsigned 64-bit integer +/// Value of #wasmtime_component_kind_t indicating an unsigned 64-bit integer #define WASMTIME_COMPONENT_KIND_U64 8 -/// \brief Value of #wasmtime_component_kind_t indicating an 32-bit floating point number +/// Value of #wasmtime_component_kind_t indicating a 32-bit floating point +/// number #define WASMTIME_COMPONENT_KIND_F32 9 -/// \brief Value of #wasmtime_component_kind_t indicating an 64-bit floating point number +/// Value of #wasmtime_component_kind_t indicating a 64-bit floating point +/// number #define WASMTIME_COMPONENT_KIND_F64 10 -/// \brief Value of #wasmtime_component_kind_t indicating a unicode character +/// Value of #wasmtime_component_kind_t indicating a unicode character #define WASMTIME_COMPONENT_KIND_CHAR 11 -/// \brief Value of #wasmtime_component_kind_t indicating a unicode string +/// Value of #wasmtime_component_kind_t indicating a unicode string #define WASMTIME_COMPONENT_KIND_STRING 12 -/// \brief Value of #wasmtime_component_kind_t indicating a list +/// Value of #wasmtime_component_kind_t indicating a list #define WASMTIME_COMPONENT_KIND_LIST 13 -/// \brief Value of #wasmtime_component_kind_t indicating a record +/// Value of #wasmtime_component_kind_t indicating a record #define WASMTIME_COMPONENT_KIND_RECORD 14 -/// \brief Value of #wasmtime_component_kind_t indicating a tuple +/// Value of #wasmtime_component_kind_t indicating a tuple #define WASMTIME_COMPONENT_KIND_TUPLE 15 -/// \brief Value of #wasmtime_component_kind_t indicating a variant +/// Value of #wasmtime_component_kind_t indicating a variant #define WASMTIME_COMPONENT_KIND_VARIANT 16 -/// \brief Value of #wasmtime_component_kind_t indicating an enum +/// Value of #wasmtime_component_kind_t indicating an enum #define WASMTIME_COMPONENT_KIND_ENUM 17 -/// \brief Value of #wasmtime_component_kind_t indicating an option +/// Value of #wasmtime_component_kind_t indicating an option #define WASMTIME_COMPONENT_KIND_OPTION 18 -/// \brief Value of #wasmtime_component_kind_t indicating a result +/// Value of #wasmtime_component_kind_t indicating a result #define WASMTIME_COMPONENT_KIND_RESULT 19 -/// \brief Value of #wasmtime_component_kind_t indicating a set of flags +/// Value of #wasmtime_component_kind_t indicating a set of flags #define WASMTIME_COMPONENT_KIND_FLAGS 20 - // forward declarations typedef struct wasmtime_component_val_t wasmtime_component_val_t; -typedef struct wasmtime_component_val_record_field_t wasmtime_component_val_record_field_t; +typedef struct wasmtime_component_val_record_field_t + wasmtime_component_val_record_field_t; typedef struct wasmtime_component_type_t wasmtime_component_type_t; typedef struct wasmtime_component_type_field_t wasmtime_component_type_field_t; @@ -104,33 +109,35 @@ typedef struct wasmtime_component_type_field_t wasmtime_component_type_field_t; WASM_API_EXTERN void wasmtime_component_##name##_new( \ wasmtime_component_##name##_t *out, size_t, element const[]); -/// \brief A vector of values. +/// A vector of values. WASMTIME_COMPONENT_DECLARE_VEC(val_vec, wasmtime_component_val_t); -/// \brief A tuple of named fields. -WASMTIME_COMPONENT_DECLARE_VEC(val_record, wasmtime_component_val_record_field_t); +/// A tuple of named fields. +WASMTIME_COMPONENT_DECLARE_VEC(val_record, + wasmtime_component_val_record_field_t); -/// \brief A variable sized bitset. +/// A variable sized bitset. WASMTIME_COMPONENT_DECLARE_VEC(val_flags, uint32_t); WASMTIME_COMPONENT_DECLARE_VEC_NEW(val_flags, uint32_t); -/// \brief A vector of types +/// A vector of types WASMTIME_COMPONENT_DECLARE_VEC(type_vec, wasmtime_component_type_t); -/// \brief A vector of field types +/// A vector of field types WASMTIME_COMPONENT_DECLARE_VEC(type_field_vec, wasmtime_component_type_field_t); -/// \brief A vector of strings +/// A vector of strings WASMTIME_COMPONENT_DECLARE_VEC(string_vec, wasm_name_t); WASMTIME_COMPONENT_DECLARE_VEC_NEW(string_vec, wasm_name_t); #undef WASMTIME_COMPONENT_DECLARE_VEC -/// \brief Representation of a variant value +/// Representation of a variant value typedef struct wasmtime_component_val_variant_t { - /// \brief Discriminant indicating the index of the variant case of this value + /// Discriminant indicating the index of the variant case of this value uint32_t discriminant; - /// \brief #wasmtime_component_val_t value of the variant case of this value if it has one + /// #wasmtime_component_val_t value of the variant case of this value if it + /// has one wasmtime_component_val_t *val; } wasmtime_component_val_variant_t; @@ -140,192 +147,226 @@ typedef struct wasmtime_component_val_variant_t { * A result is an either type holding an ok value or an error */ typedef struct wasmtime_component_val_result_t { - /// \brief Value of the result, either of the ok type or of the error type, depending on #error + /// Value of the result, either of the ok type or of the error type, depending + /// on #error wasmtime_component_val_t *val; - /// \brief Discriminant indicating if this result is an ok value or an error + /// Discriminant indicating if this result is an ok value or an error bool error; } wasmtime_component_val_result_t; -/// \brief Representation of an enum value +/// Representation of an enum value typedef struct wasmtime_component_val_enum_t { - /// \brief Discriminant indicating the index of this value in the enum + /// Discriminant indicating the index of this value in the enum uint32_t discriminant; } wasmtime_component_val_enum_t; /** * \brief Container for different kind of component model value data * - * Setting any dynamic data to one of this field means that the payload now owns it + * Setting dynamic data to one of this field means that the payload now owns it */ typedef union wasmtime_component_val_payload_t { - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_BOOLEAN + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_BOOLEAN bool boolean; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_S8 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_S8 int8_t s8; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_U8 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_U8 uint8_t u8; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_S16 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_S16 int16_t s16; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_U16 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_U16 uint16_t u16; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_S32 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_S32 int32_t s32; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_U32 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_U32 uint32_t u32; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_S64 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_S64 int64_t s64; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_U64 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_U64 uint64_t u64; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_F32 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_F32 float f32; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_F64 + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_F64 double f64; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_CHARACTER + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_CHARACTER uint8_t character; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_STRING + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_STRING wasm_name_t string; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_LIST + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_LIST wasmtime_component_val_vec_t list; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_RECORD + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_RECORD wasmtime_component_val_record_t record; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_TUPLE + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_TUPLE wasmtime_component_val_vec_t tuple; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_VARIANT + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_VARIANT wasmtime_component_val_variant_t variant; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_ENUMERATION + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_ENUMERATION wasmtime_component_val_enum_t enumeration; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_OPTION + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_OPTION wasmtime_component_val_t *option; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_RESULT + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_RESULT wasmtime_component_val_result_t result; - /// \brief Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_KIND_FLAGS + /// Field used if #wasmtime_component_val_t::kind is + /// #WASMTIME_COMPONENT_KIND_FLAGS wasmtime_component_val_flags_t flags; } wasmtime_component_val_payload_t; /** * \brief Representation of a component model value * - * Many kind of values own data, so those need to be properly dropped in wasmtime, - * and therefore should not live on the stack. + * Many kind of values own data, so those need to be properly dropped in + * wasmtime, and therefore should not live on the stack. */ typedef struct wasmtime_component_val_t { - /// \brief Discriminant indicating which field of #payload is valid + /// Discriminant indicating which field of #payload is valid wasmtime_component_kind_t kind; - /// \brief Container for the value data + /// Container for the value data wasmtime_component_val_payload_t payload; } wasmtime_component_val_t; WASMTIME_COMPONENT_DECLARE_VEC_NEW(val_vec, wasmtime_component_val_t); -/// \brief Representation of record field. +/// Representation of record field. typedef struct wasmtime_component_val_record_field_t { - /// \brief Name of the field + /// Name of the field wasm_name_t name; - /// \brief Value of the field + /// Value of the field wasmtime_component_val_t val; } wasmtime_component_val_record_field_t; -WASMTIME_COMPONENT_DECLARE_VEC_NEW(val_record, wasmtime_component_val_record_field_t); +WASMTIME_COMPONENT_DECLARE_VEC_NEW(val_record, + wasmtime_component_val_record_field_t); /** - * \brief Sets the value of a flag within within a #wasmtime_component_val_flags_t. + * \brief Sets the value of a flag within within a + #wasmtime_component_val_flags_t. * * If this bit set is too small to hold a value at `index` it will be resized. - + * * \param flags the #wasmtime_component_val_flags_t to modify * \param index the index of the flag to modify * \param enabled the value to set the flag to */ -void wasmtime_component_val_flags_set(wasmtime_component_val_flags_t *flags, uint32_t index, bool enabled); +void wasmtime_component_val_flags_set(wasmtime_component_val_flags_t *flags, + uint32_t index, bool enabled); /** - * \brief Tests the value of a flag within within a #wasmtime_component_val_flags_t. + * \brief Tests the value of a flag within within a + #wasmtime_component_val_flags_t. * * If this bit set is too small to hold a value at `index` it will be resized. - + * * \param flags the #wasmtime_component_val_flags_t to test * \param index the index of the flag to test + * * \return true if the flag is set, else false */ -bool wasmtime_component_val_flags_test(const wasmtime_component_val_flags_t* flags, uint32_t index); +bool wasmtime_component_val_flags_test( + const wasmtime_component_val_flags_t *flags, uint32_t index); /** * \brief Creates a new #wasmtime_component_val_t * - * This is usually used to create inner values, typically as part of an option or result. - * In this case, ownership is given out to the outer value. + * This is usually used to create inner values, typically as part of an option + * or result. In this case, ownership is given out to the outer value. * - * In case where a top level #wasmtime_component_val_t is created (for example to be passed directly - * to #wasmtime_component_func_call), then it should be deleted with #wasmtime_component_val_delete + * In case where a top level #wasmtime_component_val_t is created (for example + * to be passed directly to #wasmtime_component_func_call), then it should be + * deleted with #wasmtime_component_val_delete * * \return a pointer to the newly created #wasmtime_component_val_t */ -wasmtime_component_val_t* wasmtime_component_val_new(); +wasmtime_component_val_t *wasmtime_component_val_new(); /** - * \brief Deletes a #wasmtime_component_val_t previously created by #wasmtime_component_val_new + * \brief Deletes a #wasmtime_component_val_t previously created by + * #wasmtime_component_val_new * - * This should not be called if the value has been given out as part of an outer #wasmtime_component_val_t + * This should not be called if the value has been given out as part of an outer + * #wasmtime_component_val_t * * \param val the #wasmtime_component_val_t to delete */ -void wasmtime_component_val_delete(wasmtime_component_val_t* val); +void wasmtime_component_val_delete(wasmtime_component_val_t *val); -/** - * \brief Representation of a field in a record type or a case in a variant type - */ +/// Representation of a field in a record type or a case in a variant type typedef struct wasmtime_component_type_field_t { - /// \brief Name of the record field or variant case + /// Name of the record field or variant case wasm_name_t name; - /// \brief Type of the record field or variant case (may be null for variant case) - wasmtime_component_type_t* ty; + /// Type of the record field or variant case (may be null for variant case) + wasmtime_component_type_t *ty; } wasmtime_component_type_field_t; -WASMTIME_COMPONENT_DECLARE_VEC_NEW(type_field_vec, wasmtime_component_type_field_t); +WASMTIME_COMPONENT_DECLARE_VEC_NEW(type_field_vec, + wasmtime_component_type_field_t); -/** - * \brief Representation of a result type - */ +/// Representation of a result type typedef struct wasmtime_component_type_result_t { - /// \brief Type of the ok value (if there is one) - wasmtime_component_type_t* ok_ty; - /// \brief Type of the error value (if there is one) - wasmtime_component_type_t* err_ty; + /// Type of the ok value (if there is one) + wasmtime_component_type_t *ok_ty; + /// Type of the error value (if there is one) + wasmtime_component_type_t *err_ty; } wasmtime_component_type_result_t; -/** - * \brief Container for different kind of component model type data - */ -typedef union wasmtime_component_type_payload_t -{ - /// \brief Field used if #wasmtime_component_type_t::kind is #WASMTIME_COMPONENT_KIND_LIST - wasmtime_component_type_t* list; - /// \brief Field used if #wasmtime_component_type_t::kind is #WASMTIME_COMPONENT_KIND_RECORD +/// Container for different kind of component model type data +typedef union wasmtime_component_type_payload_t { + /// Field used if #wasmtime_component_type_t::kind is + /// #WASMTIME_COMPONENT_KIND_LIST + wasmtime_component_type_t *list; + /// Field used if #wasmtime_component_type_t::kind is + /// #WASMTIME_COMPONENT_KIND_RECORD wasmtime_component_type_field_vec_t record; - /// \brief Field used if #wasmtime_component_type_t::kind is #WASMTIME_COMPONENT_KIND_TUPLE + /// Field used if #wasmtime_component_type_t::kind is + /// #WASMTIME_COMPONENT_KIND_TUPLE wasmtime_component_type_vec_t tuple; - /// \brief Field used if #wasmtime_component_type_t::kind is #WASMTIME_COMPONENT_KIND_VARIANT + /// Field used if #wasmtime_component_type_t::kind is + /// #WASMTIME_COMPONENT_KIND_VARIANT wasmtime_component_type_field_vec_t variant; - /// \brief Field used if #wasmtime_component_type_t::kind is #WASMTIME_COMPONENT_KIND_ENUM + /// Field used if #wasmtime_component_type_t::kind is + /// #WASMTIME_COMPONENT_KIND_ENUM wasmtime_component_string_vec_t enumeration; - /// \brief Field used if #wasmtime_component_type_t::kind is #WASMTIME_COMPONENT_KIND_OPTION - wasmtime_component_type_t* option; - /// \brief Field used if #wasmtime_component_type_t::kind is #WASMTIME_COMPONENT_KIND_RESULT + /// Field used if #wasmtime_component_type_t::kind is + /// #WASMTIME_COMPONENT_KIND_OPTION + wasmtime_component_type_t *option; + /// Field used if #wasmtime_component_type_t::kind is + /// #WASMTIME_COMPONENT_KIND_RESULT wasmtime_component_type_result_t result; - /// \brief Field used if #wasmtime_component_type_t::kind is #WASMTIME_COMPONENT_KIND_FLAGS + /// Field used if #wasmtime_component_type_t::kind is + /// #WASMTIME_COMPONENT_KIND_FLAGS wasmtime_component_string_vec_t flags; } wasmtime_component_type_payload_t; /** * \brief Representation of a component model type * - * Many kind of types own data, so those need to be properly dropped in wasmtime, - * and therefore should not live on the stack. + * Many kind of types own data, so those need to be properly dropped in + * wasmtime, and therefore should not live on the stack. */ typedef struct wasmtime_component_type_t { - /// \brief Discriminant indicating what kind of type it is, and which field of #payload is valid, if any + /// Discriminant indicating what kind of type it is, and which field of + /// #payload is valid, if any wasmtime_component_kind_t kind; - /// \brief Container for the type data, if any + /// Container for the type data, if any wasmtime_component_type_payload_t payload; } wasmtime_component_type_t; @@ -336,36 +377,39 @@ WASMTIME_COMPONENT_DECLARE_VEC_NEW(type_vec, wasmtime_component_type_t); /** * \brief Creates a new #wasmtime_component_type_t * - * This is usually used to create inner types, typically as part of an option or result. - * In this case, ownership is given out to the outer value. + * This is usually used to create inner types, typically as part of an option or + * result. In this case, ownership is given out to the outer value. * - * In case where a top level #wasmtime_component_type_t is created (for example to be passed directly to - * #wasmtime_component_linker_define_func), then it should be deleted with #wasmtime_component_type_delete + * In case where a top level #wasmtime_component_type_t is created (for example + * to be passed directly to #wasmtime_component_linker_define_func), then it + * should be deleted with #wasmtime_component_type_delete * * \return a pointer to the newly created #wasmtime_component_type_t */ -wasmtime_component_type_t* wasmtime_component_type_new(); +wasmtime_component_type_t *wasmtime_component_type_new(); /** - * \brief Deletes a #wasmtime_component_type_t previously created by #wasmtime_component_type_new + * \brief Deletes a #wasmtime_component_type_t previously created by + * #wasmtime_component_type_new * - * This should not be called if the type has been given out as part of an outer #wasmtime_component_type_t + * This should not be called if the type has been given out as part of an outer + * #wasmtime_component_type_t * * \param val the #wasmtime_component_type_t to delete */ -void wasmtime_component_type_delete(wasmtime_component_type_t* ty); +void wasmtime_component_type_delete(wasmtime_component_type_t *ty); -/** - * \brief Representation of a component in the component model. - */ +/// Representation of a component in the component model. typedef struct wasmtime_component_t wasmtime_component_t; /** * \brief Compiles a WebAssembly binary into a #wasmtime_component_t * - * This function will compile a WebAssembly binary into an owned #wasmtime_component_t. + * This function will compile a WebAssembly binary into an owned + #wasmtime_component_t. * - * It requires a component binary, such as what is produced by Rust `cargo component` tooling. + * It requires a component binary, such as what is produced by Rust `cargo + component` tooling. * * This function does not take ownership of any of its arguments, but the * returned error and component are owned by the caller. @@ -373,15 +417,19 @@ typedef struct wasmtime_component_t wasmtime_component_t; * \param engine the #wasm_engine_t that will create the component * \param buf the address of the buffer containing the WebAssembly binary * \param len the length of the buffer containing the WebAssembly binary - * \param component_out on success, contains the address of the created component + * \param component_out on success, contains the address of the created + * component + * * \return NULL on success, else a #wasmtime_error_t describing the error */ wasmtime_error_t * -wasmtime_component_from_binary(const wasm_engine_t *engine, const uint8_t *buf, size_t len, +wasmtime_component_from_binary(const wasm_engine_t *engine, const uint8_t *buf, + size_t len, wasmtime_component_t **component_out); /** - * \brief Deletes a #wasmtime_component_t created by #wasmtime_component_from_binary + * \brief Deletes a #wasmtime_component_t created by + * #wasmtime_component_from_binary * * \param component the component to delete */ @@ -395,9 +443,9 @@ void wasmtime_component_delete(wasmtime_component_t *component); * Due to the interaction between `wasmtime::component::Linker` and * `wasmtime::component::LinkerInstance`, the latter being more of a builder, * it is expected to first define the host functions through calls to - * #wasmtime_component_linker_define_func, then call #wasmtime_component_linker_build - * to create and populate the root `wasmtime::component::LinkerInstance` and it's - * descendants (if any). + * #wasmtime_component_linker_define_func, then call + * #wasmtime_component_linker_build to create and populate the root + * `wasmtime::component::LinkerInstance` and it's descendants (if any). */ typedef struct wasmtime_component_linker_t wasmtime_component_linker_t; @@ -405,18 +453,21 @@ typedef struct wasmtime_component_linker_t wasmtime_component_linker_t; * \brief Creates a new #wasmtime_component_linker_t for the specified engine. * * \param engine the compilation environment and configuration + * * \return a pointer to the newly created #wasmtime_component_linker_t */ -wasmtime_component_linker_t *wasmtime_component_linker_new(const wasm_engine_t *engine); +wasmtime_component_linker_t * +wasmtime_component_linker_new(const wasm_engine_t *engine); /** - * \brief Deletes a #wasmtime_component_linker_t created by #wasmtime_component_linker_new + * \brief Deletes a #wasmtime_component_linker_t created by + * #wasmtime_component_linker_new * * \param linker the #wasmtime_component_linker_t to delete */ void wasmtime_component_linker_delete(wasmtime_component_linker_t *linker); -/// \brief Representation of a component instance +/// Representation of a component instance typedef struct wasmtime_component_instance_t wasmtime_component_instance_t; // declaration from store.h @@ -428,7 +479,8 @@ typedef struct wasmtime_context wasmtime_context_t; * This is the function signature for host functions that can be made accessible * to WebAssembly components. The arguments to this function are: * - * \param env a user-provided argument passed to #wasmtime_component_linker_define_func + * \param env a user-provided argument passed to + * #wasmtime_component_linker_define_func * \param context a #wasmtime_context_t, the context of this call * \param args the arguments provided to this function invocation * \param nargs how many arguments are provided @@ -444,8 +496,9 @@ typedef struct wasmtime_context wasmtime_context_t; * relinquishes ownership of the trap and it is passed back to the engine. */ typedef wasm_trap_t *(*wasmtime_component_func_callback_t)( - void *env, wasmtime_context_t *context, const wasmtime_component_val_t *args, - size_t nargs, wasmtime_component_val_t *results, size_t nresults); + void *env, wasmtime_context_t *context, + const wasmtime_component_val_t *args, size_t nargs, + wasmtime_component_val_t *results, size_t nresults); /** * \brief Defines a host function in a linker @@ -454,62 +507,80 @@ typedef wasm_trap_t *(*wasmtime_component_func_callback_t)( * * Does not take ownership of the #wasmtime_component_type_t arguments. * - * \param linker the #wasmtime_component_linker_t in which the function should be defined - * \param path the dot-separated path of the package where the function is defined + * \param linker the #wasmtime_component_linker_t in which the function should + * be defined + * \param path the dot-separated path of the package where the function is + * defined * \param path_len the byte length of `path` * \param name the name of the function * \param name_len the byte length of `name` - * \param params_types_buf a pointer to an array of #wasmtime_component_type_t describing the function's parameters + * \param params_types_buf a pointer to an array of #wasmtime_component_type_t + * describing the function's parameters * \param params_types_len the length of `params_types_buf` - * \param outputs_types_buf a pointer to an array of #wasmtime_component_type_t describing the function's outputs + * \param outputs_types_buf a pointer to an array of #wasmtime_component_type_t + * describing the function's outputs * \param outputs_types_len the length of `outputs_types_buf` - * \param cb a pointer to the actual functions, a #wasmtime_component_func_callback_t - * \param data the host-provided data to provide as the first argument to the callback + * \param cb a pointer to the actual functions, a + * #wasmtime_component_func_callback_t + * \param data the host-provided data to provide as the first argument to the + * callback * \param finalizer an optional finalizer for the `data` argument. - * \return wasmtime_error_t* on success `NULL` is returned, otherwise an error is returned which - * describes why the definition failed. + * + * \return wasmtime_error_t* on success `NULL` is returned, otherwise an error + * is returned which describes why the definition failed. */ wasmtime_error_t *wasmtime_component_linker_define_func( wasmtime_component_linker_t *linker, const char *path, size_t path_len, const char *name, size_t name_len, - wasmtime_component_type_t* params_types_buf, size_t params_types_len, - wasmtime_component_type_t* outputs_types_buf, size_t outputs_types_len, - wasmtime_component_func_callback_t cb, void *data, void (*finalizer)(void *)); + wasmtime_component_type_t *params_types_buf, size_t params_types_len, + wasmtime_component_type_t *outputs_types_buf, size_t outputs_types_len, + wasmtime_component_func_callback_t cb, void *data, + void (*finalizer)(void *)); /** - * \brief Builds the linker, providing the host functions defined by calls to #wasmtime_component_linker_define_func + * \brief Builds the linker, providing the host functions defined by calls to + * #wasmtime_component_linker_define_func * * \param linker the #wasmtime_component_linker_t to build - * \return wasmtime_error_t* On success `NULL` is returned, otherwise an error is returned which - * describes why the build failed. + * + * \return wasmtime_error_t* On success `NULL` is returned, otherwise an error + * is returned which describes why the build failed. */ -wasmtime_error_t *wasmtime_component_linker_build(wasmtime_component_linker_t *linker); +wasmtime_error_t * +wasmtime_component_linker_build(wasmtime_component_linker_t *linker); /** * \brief Instantiates a component instance in a given #wasmtime_context_t * - * \param linker a #wasmtime_component_linker_t that will help provide host functions - * \param context the #wasmtime_context_t in which the instance should be created + * \param linker a #wasmtime_component_linker_t that will help provide host + * functions + * \param context the #wasmtime_context_t in which the instance should be + * created * \param component the #wasmtime_component_t to instantiate - * \param instance_out on success, the instantiated #wasmtime_component_instance_t - * \return wasmtime_error_t* on success `NULL` is returned, otherwise an error is returned which - * describes why the build failed. + * \param instance_out on success, the instantiated + * #wasmtime_component_instance_t + * + * \return wasmtime_error_t* on success `NULL` is returned, otherwise an error + * is returned which describes why the build failed. */ wasmtime_error_t *wasmtime_component_linker_instantiate( const wasmtime_component_linker_t *linker, wasmtime_context_t *context, - const wasmtime_component_t *component, wasmtime_component_instance_t **instance_out); + const wasmtime_component_t *component, + wasmtime_component_instance_t **instance_out); -/// \brief Representation of an exported function in Wasmtime component model. +/// Representation of an exported function in Wasmtime component model. typedef struct wasmtime_component_func_t wasmtime_component_func_t; /** * \brief Looks for an exported function in the given component instance * - * \param instance the #wasmtime_component_instance_t in which the function should be looked for + * \param instance the #wasmtime_component_instance_t in which the function + * should be looked for * \param context the #wasmtime_context_t that contains `instance` * \param name the name of function to look for * \param name_len the byte length of `name` * \param item_out the wasmtime_component_func_t that was found, if any + * * \return true if the function was found, else false */ bool wasmtime_component_instance_get_func( @@ -519,28 +590,37 @@ bool wasmtime_component_instance_get_func( /** * \brief Calls an exported function of a component * - * It is the responsibility of the caller to make sure that `params` has the expected - * length, and the correct types, else the call will error out. `results` must have the - * expected length, but the values will be written with the correct types. - * - * This can fail in two ways : either a non-NULL #wasmtime_error_t is returned, for example if the - * parameters are incorrect (and `trap_out` will be NULL), or the call may trap, in which case - * NULL is returned, but `trap_out` will be non-NULL. - * - * Does not take ownership of #wasmtime_component_val_t arguments. Gives ownership of - * #wasmtime_component_val_t results. As such, if those are data-owning values, they - * should be created and deleted through this api, either directly with #wasmtime_component_val_new, - * or through a #wasmtime_component_val_vec_t, using #wasmtime_component_val_vec_new and + * It is the responsibility of the caller to make sure that `params` has the + * expected length, and the correct types, else the call will error out. + * `results` must have the expected length, but the values will be written with + * the correct types. + * + * This can fail in two ways : either a non-NULL #wasmtime_error_t is returned, + * for example if the parameters are incorrect (and `trap_out` will be NULL), or + * the call may trap, in which case NULL is returned, but `trap_out` will be + * non-NULL. + * + * Does not take ownership of #wasmtime_component_val_t arguments. Gives + * ownership of #wasmtime_component_val_t results. As such, if those are + * data-owning values, they should be created and deleted through this api, + * either directly with #wasmtime_component_val_new, or through a + * #wasmtime_component_val_vec_t, using #wasmtime_component_val_vec_new and * #wasmtime_component_val_vec_delete * - * \param func the function to call, typically found with #wasmtime_component_instance_get_func + * \param func the function to call, typically found with + * #wasmtime_component_instance_get_func * \param context the #wasmtime_context_t that contains `func` - * \param params the parameters of `func`, as an array of #wasmtime_component_val_t + * \param params the parameters of `func`, as an array of + * #wasmtime_component_val_t * \param params_len the length of `params` - * \param results the results of `func`, as an array of #wasmtime_component_val_t that will be written + * \param results the results of `func`, as an array of + * #wasmtime_component_val_t that will be written * \param results_len the length of `results` - * \param trap_out NULL if the call completed successfully or couldn't be made, otherwise the trap that was raised - * \return wasmtime_error_t* NULL on success or a description of the error calling the function + * \param trap_out NULL if the call completed successfully or couldn't be made, + * otherwise the trap that was raised + * + * \return wasmtime_error_t* NULL on success or a description of the error + * calling the function */ wasmtime_error_t *wasmtime_component_func_call( const wasmtime_component_func_t *func, wasmtime_context_t *context, diff --git a/crates/c-api/src/lib.rs b/crates/c-api/src/lib.rs index c5db0ddc8579..5b78fe15ad34 100644 --- a/crates/c-api/src/lib.rs +++ b/crates/c-api/src/lib.rs @@ -15,7 +15,6 @@ #![expect(non_camel_case_types, reason = "matching C style, not Rust")] pub use wasmtime; -use wasmtime::Trap; mod config; mod engine; @@ -127,10 +126,12 @@ unsafe fn slice_from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T } } +#[cfg(any(feature = "async", feature = "component-model"))] pub(crate) fn handle_call_error( err: wasmtime::Error, trap_ret: &mut *mut wasm_trap_t, ) -> Option> { + use wasmtime::Trap; if err.is::() { *trap_ret = Box::into_raw(Box::new(wasm_trap_t::new(err))); None diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 927b66d57867..1f4860a17dc3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -66,6 +66,9 @@ create_rust_wasm(fib-debug wasm32-unknown-unknown) create_rust_wasm(tokio wasm32-wasip1) create_rust_wasm(wasi wasm32-wasip1) create_rust_wasm(component wasm32-unknown-unknown) +# the C test for component needs a component binary, not a plain module +# this is done using the rust example to do the conversion +execute_process(COMMAND cargo run --example component copy WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/..) create_rust_test(epochs) create_rust_test(externref) create_rust_test(fib-debug) diff --git a/examples/component/main.c b/examples/component/main.c index ffb54cca59b5..7813e252a7ed 100644 --- a/examples/component/main.c +++ b/examples/component/main.c @@ -6,19 +6,18 @@ #include #include -const char* multiply_data = "hello multiply"; -const char* apply_data = "hello apply"; -const char* context_data = "context data"; +const char *multiply_data = "hello multiply"; +const char *apply_data = "hello apply"; +const char *context_data = "context data"; static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap); -wasm_trap_t *mult( - void *env, wasmtime_context_t *context, const wasmtime_component_val_t *args, - size_t nargs, wasmtime_component_val_t *results, size_t nresults) -{ - assert(env == (void*)multiply_data); - const char* exec_env = (const char*)wasmtime_context_get_data(context); +wasm_trap_t *mult(void *env, wasmtime_context_t *context, + const wasmtime_component_val_t *args, size_t nargs, + wasmtime_component_val_t *results, size_t nresults) { + assert(env == (void *)multiply_data); + const char *exec_env = (const char *)wasmtime_context_get_data(context); assert(exec_env == context_data); assert(nargs == 2); assert(nresults == 1); @@ -30,20 +29,20 @@ wasm_trap_t *mult( return NULL; } -wasm_trap_t *apply( - void *env, wasmtime_context_t *context, const wasmtime_component_val_t *args, - size_t nargs, wasmtime_component_val_t *results, size_t nresults) -{ - assert(env == (void*)apply_data); - const char* exec_env = (const char*)wasmtime_context_get_data(context); +wasm_trap_t *apply(void *env, wasmtime_context_t *context, + const wasmtime_component_val_t *args, size_t nargs, + wasmtime_component_val_t *results, size_t nresults) { + assert(env == (void *)apply_data); + const char *exec_env = (const char *)wasmtime_context_get_data(context); assert(exec_env == context_data); assert(nargs == 3); assert(nresults == 1); assert(args[0].kind == WASMTIME_COMPONENT_KIND_F32); assert(args[1].kind == WASMTIME_COMPONENT_KIND_F32); assert(args[2].kind == WASMTIME_COMPONENT_KIND_ENUM); - float res = args[2].payload.enumeration.discriminant == 0 ? - args[0].payload.f32 + args[1].payload.f32 : args[0].payload.f32 * args[1].payload.f32; + float res = args[2].payload.enumeration.discriminant == 0 + ? args[0].payload.f32 + args[1].payload.f32 + : args[0].payload.f32 * args[1].payload.f32; results[0].kind = WASMTIME_COMPONENT_KIND_F32; results[0].payload.f32 = res; return NULL; @@ -54,31 +53,37 @@ int main() { // Create a component linker with host functions defined wasmtime_component_linker_t *linker = wasmtime_component_linker_new(engine); - // `multiply` only uses types without additional owned data, that can live on the stack + // `multiply` only uses types without additional owned data, that can live on + // the stack wasmtime_component_type_t mult_param_types[2]; mult_param_types[0].kind = WASMTIME_COMPONENT_KIND_F32; mult_param_types[1].kind = WASMTIME_COMPONENT_KIND_F32; wasmtime_component_type_t f32_result_type; f32_result_type.kind = WASMTIME_COMPONENT_KIND_F32; - wasmtime_error_t* error = wasmtime_component_linker_define_func( - linker, "host", 4, "multiply", 8, mult_param_types, 2, - &f32_result_type, 1, mult, (void*)multiply_data, NULL); + wasmtime_error_t *error = wasmtime_component_linker_define_func( + linker, "host", 4, "multiply", 8, mult_param_types, 2, &f32_result_type, + 1, mult, (void *)multiply_data, NULL); if (error) exit_with_error("failed to define function multiply", error, NULL); - // `apply` uses an enum, which needs additional data, use a wasmtime_component_type_vec_t + // `apply` uses an enum, which needs additional data, use a + // wasmtime_component_type_vec_t wasmtime_component_type_vec_t apply_param_types; wasmtime_component_type_vec_new_uninitialized(&apply_param_types, 3); apply_param_types.data[0].kind = WASMTIME_COMPONENT_KIND_F32; apply_param_types.data[1].kind = WASMTIME_COMPONENT_KIND_F32; apply_param_types.data[2].kind = WASMTIME_COMPONENT_KIND_ENUM; - wasmtime_component_string_vec_new_uninitialized(&apply_param_types.data[2].payload.enumeration, 2); - wasm_name_new_from_string(&apply_param_types.data[2].payload.enumeration.data[0], "add"); - wasm_name_new_from_string(&apply_param_types.data[2].payload.enumeration.data[1], "multiply"); + wasmtime_component_string_vec_new_uninitialized( + &apply_param_types.data[2].payload.enumeration, 2); + wasm_name_new_from_string( + &apply_param_types.data[2].payload.enumeration.data[0], "add"); + wasm_name_new_from_string( + &apply_param_types.data[2].payload.enumeration.data[1], "multiply"); error = wasmtime_component_linker_define_func( - linker, "host", 4, "apply", 5, apply_param_types.data, apply_param_types.size, - &f32_result_type, 1, apply, (void*)apply_data, NULL); + linker, "host", 4, "apply", 5, apply_param_types.data, + apply_param_types.size, &f32_result_type, 1, apply, (void *)apply_data, + NULL); if (error) exit_with_error("failed to define function apply", error, NULL); // deleting the vector also drops the full types hierarchy @@ -90,9 +95,13 @@ int main() { // Load binary. printf("Loading binary...\n"); - FILE *file = fopen("target/wasm32-unknown-unknown/debug/guest.wasm", "rb"); + // Note that the binary should be a component (not a plain module), typically + // built by running `cargo component build -p example-component-wasm --target + // wasm32-unknown-unknown`, here created with a secondary usage of rust test + FILE *file = + fopen("target/wasm32-unknown-unknown/debug/guest-component.wasm", "rb"); if (!file) { - printf("> Error opening module!\n"); + printf("> Error opening component!\n"); return 1; } fseek(file, 0L, SEEK_END); @@ -101,41 +110,44 @@ int main() { wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { - printf("> Error reading module!\n"); + printf("> Error reading component!\n"); return 1; } fclose(file); // Compile. - // Note that the binary should be a component (not a plain module), typically built by running - // `cargo component build -p example-component-wasm --target wasm32-unknown-unknown` - // this will therefore fail if only the README instructions are followed printf("Compiling component...\n"); - wasmtime_component_t* component; - error = wasmtime_component_from_binary(engine, (uint8_t *)binary.data, binary.size, &component); + wasmtime_component_t *component; + error = wasmtime_component_from_binary(engine, (uint8_t *)binary.data, + binary.size, &component); if (error) exit_with_error("failed to build component", error, NULL); wasm_byte_vec_delete(&binary); - wasmtime_store_t *store = wasmtime_store_new(engine, (void*)context_data, NULL); + wasmtime_store_t *store = + wasmtime_store_new(engine, (void *)context_data, NULL); wasmtime_context_t *context = wasmtime_store_context(store); // Instantiate. printf("Instantiating component...\n"); wasmtime_component_instance_t *instance; - error = wasmtime_component_linker_instantiate(linker, context, component, &instance); + error = wasmtime_component_linker_instantiate(linker, context, component, + &instance); if (error) exit_with_error("failed to instantiate component", error, NULL); // Lookup functions. - wasmtime_component_func_t* convert1; - const char* func_name1 = "convert-celsius-to-fahrenheit"; - bool ok = wasmtime_component_instance_get_func(instance, context, func_name1, strlen(func_name1), &convert1); + wasmtime_component_func_t *convert1; + const char *func_name1 = "convert-celsius-to-fahrenheit"; + bool ok = wasmtime_component_instance_get_func(instance, context, func_name1, + strlen(func_name1), &convert1); if (!ok) - exit_with_error("function convert-celsius-to-fahrenheit not found", NULL, NULL); - wasmtime_component_func_t* convert2; - const char* func_name2 = "convert"; - ok = wasmtime_component_instance_get_func(instance, context, func_name2, strlen(func_name2), &convert2); + exit_with_error("function convert-celsius-to-fahrenheit not found", NULL, + NULL); + wasmtime_component_func_t *convert2; + const char *func_name2 = "convert"; + ok = wasmtime_component_instance_get_func(instance, context, func_name2, + strlen(func_name2), &convert2); if (!ok) exit_with_error("function convert not found", NULL, NULL); @@ -146,24 +158,27 @@ int main() { param_val.payload.f32 = 23.4f; // will be written, but must be "droppable", i.e. without owned data result_val.kind = WASMTIME_COMPONENT_KIND_BOOL; - wasm_trap_t* trap = NULL; - error = wasmtime_component_func_call(convert1, context, ¶m_val, 1, &result_val, 1, &trap); + wasm_trap_t *trap = NULL; + error = wasmtime_component_func_call(convert1, context, ¶m_val, 1, + &result_val, 1, &trap); if (error != NULL || trap != NULL) - exit_with_error("failed to call function convert-celsius-to-fahrenheit", error, trap); + exit_with_error("failed to call function convert-celsius-to-fahrenheit", + error, trap); assert(result_val.kind == WASMTIME_COMPONENT_KIND_F32); printf("23.4°C = %f°F\n", result_val.payload.f32); printf("Calling convert...\n"); - wasmtime_component_val_t* t = wasmtime_component_val_new(); + wasmtime_component_val_t *t = wasmtime_component_val_new(); t->kind = WASMTIME_COMPONENT_KIND_VARIANT; t->payload.variant.discriminant = 1; t->payload.variant.val = wasmtime_component_val_new(); t->payload.variant.val->kind = WASMTIME_COMPONENT_KIND_F32; t->payload.variant.val->payload.f32 = 66.2f; - wasmtime_component_val_t* result = wasmtime_component_val_new(); + wasmtime_component_val_t *result = wasmtime_component_val_new(); - error = wasmtime_component_func_call(convert2, context, t, 1, result, 1, &trap); + error = + wasmtime_component_func_call(convert2, context, t, 1, result, 1, &trap); if (error != NULL || trap != NULL) exit_with_error("failed to call function", error, trap); wasmtime_component_val_delete(t); diff --git a/examples/component/main.rs b/examples/component/main.rs index 784fc134bc32..5bc346fa58f6 100644 --- a/examples/component/main.rs +++ b/examples/component/main.rs @@ -49,13 +49,23 @@ fn convert_to_component(path: impl AsRef) -> Result> { } fn main() -> Result<()> { - // Create an engine with the component model enabled (disabled by default). - let engine = Engine::new(Config::new().wasm_component_model(true))?; - // NOTE: The wasm32-unknown-unknown target is used here for simplicity, real world use cases // should probably use the wasm32-wasip1 target, and enable wasi preview2 within the component // model. - let component = convert_to_component("target/wasm32-unknown-unknown/debug/guest.wasm")?; + let module_path = "target/wasm32-unknown-unknown/debug/guest.wasm"; + let component = convert_to_component(module_path)?; + + if std::env::args().len() > 1 { + // if called with an argument, just write the component binary + // this is useful for the c-api test, which doesn't expose wit_component::ComponentEncoder + let component_path = module_path.replace("guest.wasm", "guest-component.wasm"); + println!("{} bytes written to {}", component.len(), component_path); + fs::write(&component_path, &component)?; + return Ok(()); + } + + // Create an engine with the component model enabled (disabled by default). + let engine = Engine::new(Config::new().wasm_component_model(true))?; // Create our component and call our generated host functions. let component = Component::from_binary(&engine, &component)?;