Skip to content

Commit

Permalink
Expose component-model to c-api
Browse files Browse the repository at this point in the history
Step 1 :
* Component/Linker
* Value
* Calls into the component
  • Loading branch information
rockwotj authored and lanfeust69 committed Dec 10, 2024
1 parent d1ff945 commit 66c1d4e
Show file tree
Hide file tree
Showing 11 changed files with 968 additions and 8 deletions.
1 change: 1 addition & 0 deletions crates/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ logging = ['dep:env_logger']
disable-logging = ["log/max_level_off", "tracing/max_level_off"]
coredump = ["wasmtime/coredump"]
addr2line = ["wasmtime/addr2line"]
component-model = ["wasmtime/component-model", "cranelift"]
demangle = ["wasmtime/demangle"]
threads = ["wasmtime/threads"]
gc = ["wasmtime/gc"]
Expand Down
2 changes: 2 additions & 0 deletions crates/c-api/artifact/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ default = [
'gc-null',
'cranelift',
'winch',
'component-model',
# ... if you add a line above this be sure to change the other locations
# marked WASMTIME_FEATURE_LIST
]
Expand All @@ -52,6 +53,7 @@ coredump = ["wasmtime-c-api/coredump"]
addr2line = ["wasmtime-c-api/addr2line"]
demangle = ["wasmtime-c-api/demangle"]
wat = ["wasmtime-c-api/wat"]
component-model = ["wasmtime-c-api/component-model"]
threads = ["wasmtime-c-api/threads"]
gc = ["wasmtime-c-api/gc"]
gc-drc = ["wasmtime-c-api/gc-drc"]
Expand Down
1 change: 1 addition & 0 deletions crates/c-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const FEATURES: &[&str] = &[
"GC_NULL",
"CRANELIFT",
"WINCH",
"COMPONENT_MODEL",
];
// ... if you add a line above this be sure to change the other locations
// marked WASMTIME_FEATURE_LIST
Expand Down
1 change: 1 addition & 0 deletions crates/c-api/cmake/features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ feature(gc-null ON)
feature(async ON)
feature(cranelift ON)
feature(winch ON)
feature(component-model ON)
# ... if you add a line above this be sure to change the other locations
# marked WASMTIME_FEATURE_LIST
199 changes: 199 additions & 0 deletions crates/c-api/include/wasmtime/component.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/**
* The component model
*
* TODO: Write some more documentation here like in the Rust API.
*
*/

#ifndef WASMTIME_COMPONENT_H
#define WASMTIME_COMPONENT_H

#include <wasm.h>
#include <wasmtime/config.h>
#include <wasmtime/error.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* \brief Whether or not to enable support for the component model in
* Wasmtime.
*
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_component_model
*/
WASMTIME_CONFIG_PROP(void, component_model, bool)

// The tag part of wasmtime_component_val_t that specifies what variant is
// populated in wasmtime_component_val_payload_t.
typedef uint8_t wasmtime_component_kind_t;

#define WASMTIME_COMPONENT_KIND_BOOL 0
#define WASMTIME_COMPONENT_KIND_S8 1
#define WASMTIME_COMPONENT_KIND_U8 2
#define WASMTIME_COMPONENT_KIND_S16 3
#define WASMTIME_COMPONENT_KIND_U16 4
#define WASMTIME_COMPONENT_KIND_S32 5
#define WASMTIME_COMPONENT_KIND_U32 6
#define WASMTIME_COMPONENT_KIND_S64 7
#define WASMTIME_COMPONENT_KIND_U64 8
#define WASMTIME_COMPONENT_KIND_F32 9
#define WASMTIME_COMPONENT_KIND_F64 10
#define WASMTIME_COMPONENT_KIND_CHAR 11
#define WASMTIME_COMPONENT_KIND_STRING 12
#define WASMTIME_COMPONENT_KIND_LIST 13
#define WASMTIME_COMPONENT_KIND_RECORD 14
#define WASMTIME_COMPONENT_KIND_TUPLE 15
#define WASMTIME_COMPONENT_KIND_VARIANT 16
#define WASMTIME_COMPONENT_KIND_ENUM 17
#define WASMTIME_COMPONENT_KIND_OPTION 18
#define WASMTIME_COMPONENT_KIND_RESULT 19
#define WASMTIME_COMPONENT_KIND_FLAGS 20

typedef struct wasmtime_component_val_t wasmtime_component_val_t;
typedef struct wasmtime_component_val_record_field_t wasmtime_component_val_record_field_t;

#define WASMTIME_COMPONENT_DECLARE_VEC(name, element) \
typedef struct wasmtime_component_##name##_t { \
size_t size; \
element *data; \
} wasmtime_component_##name##_t; \
\
WASM_API_EXTERN void wasmtime_component_##name##_new_empty( \
wasmtime_component_##name##_t *out); \
WASM_API_EXTERN void wasmtime_component_##name##_new_uninitialized( \
wasmtime_component_##name##_t *out, size_t); \
WASM_API_EXTERN void wasmtime_component_##name##_copy( \
wasmtime_component_##name##_t *out, \
const wasmtime_component_##name##_t *); \
WASM_API_EXTERN void wasmtime_component_##name##_delete( \
wasmtime_component_##name##_t *);

// in C, an array type needs a complete element type, we need to defer xxx_new
#define WASMTIME_COMPONENT_DECLARE_VEC_NEW(name, element) \
WASM_API_EXTERN void wasmtime_component_##name##_new( \
wasmtime_component_##name##_t *out, size_t, element const[]);

/// \brief 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);

/// \brief A variable sized bitset.
WASMTIME_COMPONENT_DECLARE_VEC(val_flags, uint32_t);
WASMTIME_COMPONENT_DECLARE_VEC_NEW(val_flags, uint32_t);

#undef WASMTIME_COMPONENT_DECLARE_VEC

// A variant contains the discriminant index and an optional value that is held.
typedef struct wasmtime_component_val_variant_t {
uint32_t discriminant;
wasmtime_component_val_t *val;
} wasmtime_component_val_variant_t;

// A result is an either type holding a value and a bit if is it an ok or error
// variant.
typedef struct wasmtime_component_val_result_t {
wasmtime_component_val_t *val;
bool error;
} wasmtime_component_val_result_t;

// Which value within an enumeration is selected.
typedef struct wasmtime_component_val_enum_t {
uint32_t discriminant;
} wasmtime_component_val_enum_t;

typedef union wasmtime_component_val_payload_t {
bool boolean;
int8_t s8;
uint8_t u8;
int16_t s16;
uint16_t u16;
int32_t s32;
uint32_t u32;
int64_t s64;
uint64_t u64;
float f32;
double f64;
uint8_t character;
wasm_name_t string;
wasmtime_component_val_vec_t list;
wasmtime_component_val_record_t record;
wasmtime_component_val_vec_t tuple;
wasmtime_component_val_variant_t variant;
wasmtime_component_val_enum_t enumeration;
wasmtime_component_val_t *option;
wasmtime_component_val_result_t result;
wasmtime_component_val_flags_t flags;
} wasmtime_component_val_payload_t;

// The tagged union for a value within the component model.
typedef struct wasmtime_component_val_t {
wasmtime_component_kind_t kind;
wasmtime_component_val_payload_t payload;
} wasmtime_component_val_t;

WASMTIME_COMPONENT_DECLARE_VEC_NEW(val_vec, wasmtime_component_val_t);

// A record is a series of named fields, which are values with a string name.
typedef struct wasmtime_component_val_record_field_t {
wasm_name_t name;
wasmtime_component_val_t val;
} wasmtime_component_val_record_field_t;

WASMTIME_COMPONENT_DECLARE_VEC_NEW(val_record, wasmtime_component_val_record_field_t);

// Set a value within this bitset.
//
// If this bit set is too small to hold a value at `index` it will be resized.
void wasmtime_component_val_flags_set(wasmtime_component_val_flags_t *flags, uint32_t index, bool enabled);

// Test if this bitset holds a value at `index`.
bool wasmtime_component_val_flags_test(const wasmtime_component_val_flags_t* flags, uint32_t index);

wasmtime_component_val_t* wasmtime_component_val_new();

void wasmtime_component_val_delete(wasmtime_component_val_t* val);

typedef struct wasmtime_component_t wasmtime_component_t;

wasmtime_error_t *
wasmtime_component_from_binary(const wasm_engine_t *engine, const uint8_t *buf, size_t len,
wasmtime_component_t **component_out);

void wasmtime_component_delete(wasmtime_component_t *component);

typedef struct wasmtime_component_linker_t wasmtime_component_linker_t;

wasmtime_component_linker_t *wasmtime_component_linker_new(const wasm_engine_t *engine);

void wasmtime_component_linker_delete(wasmtime_component_linker_t *linker);

typedef struct wasmtime_component_instance_t wasmtime_component_instance_t;

// declaration from store.h
typedef struct wasmtime_context wasmtime_context_t;

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);

typedef struct wasmtime_component_func_t wasmtime_component_func_t;

bool wasmtime_component_instance_get_func(
const wasmtime_component_instance_t *instance, wasmtime_context_t *context,
const char *name, size_t name_len, wasmtime_component_func_t **item_out);

wasmtime_error_t *wasmtime_component_func_call(
const wasmtime_component_func_t *func, wasmtime_context_t *context,
const wasmtime_component_val_t *params, size_t params_len,
wasmtime_component_val_t *results, size_t results_len,
wasm_trap_t **trap_out);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // WASMTIME_COMPONENT_H
1 change: 1 addition & 0 deletions crates/c-api/include/wasmtime/conf.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#cmakedefine WASMTIME_FEATURE_ASYNC
#cmakedefine WASMTIME_FEATURE_CRANELIFT
#cmakedefine WASMTIME_FEATURE_WINCH
#cmakedefine WASMTIME_FEATURE_COMPONENT_MODEL
// ... if you add a line above this be sure to change the other locations
// marked WASMTIME_FEATURE_LIST

Expand Down
10 changes: 3 additions & 7 deletions crates/c-api/src/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};
use std::{ptr, str};
use wasmtime::{
AsContextMut, Func, Instance, Result, RootScope, StackCreator, StackMemory, Trap, Val,
};
use wasmtime::{AsContextMut, Func, Instance, Result, RootScope, StackCreator, StackMemory, Val};

use crate::{
bad_utf8, handle_result, to_str, translate_args, wasm_config_t, wasm_functype_t, wasm_trap_t,
Expand Down Expand Up @@ -211,10 +209,8 @@ fn handle_call_error(
trap_ret: &mut *mut wasm_trap_t,
err_ret: &mut *mut wasmtime_error_t,
) {
if err.is::<Trap>() {
*trap_ret = Box::into_raw(Box::new(wasm_trap_t::new(err)));
} else {
*err_ret = Box::into_raw(Box::new(wasmtime_error_t::from(err)));
if let Some(err) = crate::handle_call_error(err, trap_ret) {
*err_ret = Box::into_raw(err);
}
}

Expand Down
Loading

0 comments on commit 66c1d4e

Please sign in to comment.