Skip to content

Commit cde2e04

Browse files
authored
Fill out more of the C++ API for components (#11889)
* capi: Add a C++ API for `component::Linker` Just a bare-bones API for now with functionality that's possible to fill out. Notably instantiation and defining functions is not yet possible in C++. Some more feature-parity is also added with the core linkers as well. * capi: Add bindings for component instances * capi: Delete wasip2.h header file Upon reflection I realize that this is not actually necessary and is otherwise a duplicate of the functionality in `wasi.h`. All of the functionality in `wasi.h` is already supported to power WASIp2-defined APIs in a linker, which is enabled by the `WasiView` trait redirecting to the `WasiView for WasiP1Ctx` implementation. This is similar to how the `wasmtime` CLI works where a P1 context is always created and then it's conditionally used for either core wasm or components. Effectively this is a deletion of duplicate functionality in the C API but no underlying functionality is lost. Translating information to preexisting WASI calls will work the same as using the wasip2 APIs before. * capi: Start bindings for component functions * capi: Bind component values in the C++ API * capi: Finish bindings for component functions/linkers All the pieces are now in place to use the C++ API in testing. * Fix compilation of CLI * Fix compile on MSVC * Try again to fix msvc compat * Fix `get_f32` and `get_f64` return values * Fix signed return values * Remove no-longer-needed `capi_transfer` function * Try to fix msvc again * Remove std::optional constructor of `Val` * Fix another namespace clash on msvc * One day I surely may understand a fraction of either C++ or MSVC, but today is not that day. * Document internal macro * Add other internal docs
1 parent b8ae742 commit cde2e04

File tree

32 files changed

+1881
-765
lines changed

32 files changed

+1881
-765
lines changed

crates/c-api/include/wasmtime.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@
205205
#include <wasmtime/val.h>
206206
#include <wasmtime/async.h>
207207
#include <wasmtime/component.h>
208-
#include <wasmtime/wasip2.h>
209208
#include <wasmtime/wat.h>
210209
// IWYU pragma: end_exports
211210
// clang-format on

crates/c-api/include/wasmtime/component.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
#define WASMTIME_COMPONENT_HH
55

66
#include <wasmtime/component/component.hh>
7+
#include <wasmtime/component/func.hh>
8+
#include <wasmtime/component/instance.hh>
9+
#include <wasmtime/component/linker.hh>
10+
#include <wasmtime/component/val.hh>
711

812
#endif // WASMTIME_COMPONENT_HH

crates/c-api/include/wasmtime/component/component.hh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
* \file wasmtime/component/component.hh
33
*/
44

5-
#ifndef WASMTIME_COMPONENT_HH
6-
#define WASMTIME_COMPONENT_HH
5+
#ifndef WASMTIME_COMPONENT_COMPONENT_HH
6+
#define WASMTIME_COMPONENT_COMPONENT_HH
77

88
#include <wasmtime/conf.h>
99

@@ -39,9 +39,10 @@ class ExportIndex {
3939

4040
std::unique_ptr<wasmtime_component_export_index_t, deleter> ptr;
4141

42-
ExportIndex(wasmtime_component_export_index_t *raw) : ptr(raw) {}
43-
4442
public:
43+
/// \brief Constructs an ExportIndex from the underlying C API struct.
44+
explicit ExportIndex(wasmtime_component_export_index_t *raw) : ptr(raw) {}
45+
4546
/// Copies another index into this one.
4647
ExportIndex(const ExportIndex &other)
4748
: ptr(wasmtime_component_export_index_clone(other.ptr.get())) {}
@@ -227,4 +228,4 @@ public:
227228

228229
#endif // WASMTIME_FEATURE_COMPONENT_MODEL
229230

230-
#endif // WASMTIME_COMPONENT_HH
231+
#endif // WASMTIME_COMPONENT_COMPONENT_HH
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/// \file wasmtime/component/func.hh
2+
3+
#ifndef WASMTIME_COMPONENT_FUNC_HH
4+
#define WASMTIME_COMPONENT_FUNC_HH
5+
6+
#include <wasmtime/conf.h>
7+
8+
#ifdef WASMTIME_FEATURE_COMPONENT_MODEL
9+
10+
#include <string_view>
11+
#include <wasmtime/component/func.h>
12+
#include <wasmtime/component/val.hh>
13+
#include <wasmtime/error.hh>
14+
#include <wasmtime/span.hh>
15+
#include <wasmtime/store.hh>
16+
17+
namespace wasmtime {
18+
namespace component {
19+
20+
/**
21+
* \brief Class representing an instantiated WebAssembly component.
22+
*/
23+
class Func {
24+
wasmtime_component_func_t func;
25+
26+
public:
27+
/// \brief Constructs an Func from the underlying C API struct.
28+
explicit Func(const wasmtime_component_func_t &func) : func(func) {}
29+
30+
/// \brief Returns the underlying C API pointer.
31+
const wasmtime_component_func_t *capi() const { return &func; }
32+
33+
/// \brief Invokes this component function with the provided `args` and the
34+
/// results are placed in `results`.
35+
Result<std::monostate> call(Store::Context cx, Span<const Val> args,
36+
Span<Val> results) const {
37+
wasmtime_error_t *error = wasmtime_component_func_call(
38+
&func, cx.capi(), Val::to_capi(args.data()), args.size(),
39+
Val::to_capi(results.data()), results.size());
40+
if (error != nullptr) {
41+
return Error(error);
42+
}
43+
return std::monostate();
44+
}
45+
46+
/**
47+
* \brief Invokes the `post-return` canonical ABI option, if specified.
48+
*/
49+
Result<std::monostate> post_return(Store::Context cx) const {
50+
wasmtime_error_t *error =
51+
wasmtime_component_func_post_return(&func, cx.capi());
52+
if (error != nullptr) {
53+
return Error(error);
54+
}
55+
return std::monostate();
56+
}
57+
};
58+
59+
} // namespace component
60+
} // namespace wasmtime
61+
62+
#endif // WASMTIME_FEATURE_COMPONENT_MODEL
63+
64+
#endif // WASMTIME_COMPONENT_FUNC_H
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/// \file wasmtime/component/instance.hh
2+
3+
#ifndef WASMTIME_COMPONENT_INSTANCE_HH
4+
#define WASMTIME_COMPONENT_INSTANCE_HH
5+
6+
#include <wasmtime/conf.h>
7+
8+
#ifdef WASMTIME_FEATURE_COMPONENT_MODEL
9+
10+
#include <string_view>
11+
#include <wasmtime/component/component.hh>
12+
#include <wasmtime/component/func.hh>
13+
#include <wasmtime/component/instance.h>
14+
#include <wasmtime/store.hh>
15+
16+
namespace wasmtime {
17+
namespace component {
18+
19+
/**
20+
* \brief Class representing an instantiated WebAssembly component.
21+
*/
22+
class Instance {
23+
wasmtime_component_instance_t instance;
24+
25+
public:
26+
/// \brief Constructs an Instance from the underlying C API struct.
27+
explicit Instance(const wasmtime_component_instance_t &inst)
28+
: instance(inst) {}
29+
30+
/// \brief Looks up an exported item from this instance by name, returning the
31+
/// index at which it can be found.
32+
///
33+
/// The returned `ExportIndex` references the underlying item within this
34+
/// instance which can then be accessed via that index specifically. The
35+
/// `instance` provided as an argument to this function is the containing
36+
/// export instance, if any, that `name` is looked up under.
37+
std::optional<ExportIndex> get_export_index(Store::Context cx,
38+
const ExportIndex *instance,
39+
std::string_view name) const {
40+
wasmtime_component_export_index_t *ret =
41+
wasmtime_component_instance_get_export_index(
42+
&this->instance, cx.capi(), instance ? instance->capi() : nullptr,
43+
name.data(), name.size());
44+
if (ret == nullptr) {
45+
return std::nullopt;
46+
}
47+
return ExportIndex(ret);
48+
}
49+
50+
/// \brief Looks up an exported function by its export index.
51+
std::optional<Func> get_func(Store::Context cx,
52+
const ExportIndex &index) const {
53+
wasmtime_component_func_t ret;
54+
bool found = wasmtime_component_instance_get_func(&instance, cx.capi(),
55+
index.capi(), &ret);
56+
if (!found)
57+
return std::nullopt;
58+
return Func(ret);
59+
}
60+
61+
/// \brief Returns the underlying C API pointer.
62+
const wasmtime_component_instance_t *capi() const { return &instance; }
63+
};
64+
65+
} // namespace component
66+
} // namespace wasmtime
67+
68+
#endif // WASMTIME_FEATURE_COMPONENT_MODEL
69+
70+
#endif // WASMTIME_COMPONENT_INSTANCE_H

crates/c-api/include/wasmtime/component/linker.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ typedef struct wasmtime_component_linker_instance_t
3434
WASM_API_EXTERN wasmtime_component_linker_t *
3535
wasmtime_component_linker_new(const wasm_engine_t *engine);
3636

37+
/**
38+
* \brief Configures whether this linker allows later definitions to shadow
39+
* previous definitions.
40+
*
41+
* By default this setting is `false`.
42+
*/
43+
WASM_API_EXTERN void
44+
wasmtime_component_linker_allow_shadowing(wasmtime_component_linker_t *linker,
45+
bool allow);
46+
3747
/**
3848
* \brief Returns the "root instance" of this linker, used to define names into
3949
* the root namespace.

0 commit comments

Comments
 (0)