diff --git a/crates/c-api/include/wasmtime/component.hh b/crates/c-api/include/wasmtime/component.hh new file mode 100644 index 000000000000..c2ef6a3b6dd9 --- /dev/null +++ b/crates/c-api/include/wasmtime/component.hh @@ -0,0 +1,8 @@ +// Convenience header to include all of `wasmtime/component/*.hh`. + +#ifndef WASMTIME_COMPONENT_HH +#define WASMTIME_COMPONENT_HH + +#include + +#endif // WASMTIME_COMPONENT_HH diff --git a/crates/c-api/include/wasmtime/component/component.h b/crates/c-api/include/wasmtime/component/component.h index b2f755d1fc7d..595c040ab622 100644 --- a/crates/c-api/include/wasmtime/component/component.h +++ b/crates/c-api/include/wasmtime/component/component.h @@ -129,6 +129,13 @@ wasmtime_component_get_export_index( const wasmtime_component_export_index_t *instance_export_index, const char *name, size_t name_len); +/** + * \brief Creates a new separately-owned copy of the specified index. + */ +WASM_API_EXTERN wasmtime_component_export_index_t * +wasmtime_component_export_index_clone( + const wasmtime_component_export_index_t *index); + /** * \brief Deletes a #wasmtime_component_export_index_t * diff --git a/crates/c-api/include/wasmtime/component/component.hh b/crates/c-api/include/wasmtime/component/component.hh new file mode 100644 index 000000000000..8c60ac8875eb --- /dev/null +++ b/crates/c-api/include/wasmtime/component/component.hh @@ -0,0 +1,230 @@ +/** + * \file wasmtime/component/component.hh + */ + +#ifndef WASMTIME_COMPONENT_HH +#define WASMTIME_COMPONENT_HH + +#include + +#ifdef WASMTIME_FEATURE_COMPONENT_MODEL + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace wasmtime { +namespace component { + +/** + * \brief An index to an exported item within a particular component. + * + * This structure is acquired from a `Component` and used to lookup exports on + * instances. + */ +class ExportIndex { + friend class Component; + + struct deleter { + void operator()(wasmtime_component_export_index_t *p) const { + wasmtime_component_export_index_delete(p); + } + }; + + std::unique_ptr ptr; + + ExportIndex(wasmtime_component_export_index_t *raw) : ptr(raw) {} + +public: + /// Copies another index into this one. + ExportIndex(const ExportIndex &other) + : ptr(wasmtime_component_export_index_clone(other.ptr.get())) {} + /// Copies another index into this one. + ExportIndex &operator=(const ExportIndex &other) { + ptr.reset(wasmtime_component_export_index_clone(other.ptr.get())); + return *this; + } + + ~ExportIndex() = default; + /// Moves resources from another component into this one. + ExportIndex(ExportIndex &&other) = default; + /// Moves resources from another component into this one. + ExportIndex &operator=(ExportIndex &&other) = default; + + /// \brief Returns the underlying C API pointer. + const wasmtime_component_export_index_t *capi() const { return ptr.get(); } + + /// \brief Returns the underlying C API pointer. + wasmtime_component_export_index_t *capi() { return ptr.get(); } +}; + +/** + * \brief Representation of a compiled WebAssembly component. + */ +class Component { + struct deleter { + void operator()(wasmtime_component_t *p) const { + wasmtime_component_delete(p); + } + }; + + std::unique_ptr ptr; + + Component(wasmtime_component_t *raw) : ptr(raw) {} + +public: + /// Copies another component into this one. + Component(const Component &other) + : ptr(wasmtime_component_clone(other.ptr.get())) {} + /// Copies another component into this one. + Component &operator=(const Component &other) { + ptr.reset(wasmtime_component_clone(other.ptr.get())); + return *this; + } + ~Component() = default; + /// Moves resources from another component into this one. + Component(Component &&other) = default; + /// Moves resources from another component into this one. + Component &operator=(Component &&other) = default; + + /// \brief Returns the underlying C API pointer. + const wasmtime_component_t *capi() const { return ptr.get(); } + + /// \brief Returns the underlying C API pointer. + wasmtime_component_t *capi() { return ptr.get(); } + +#ifdef WASMTIME_FEATURE_COMPILER + /** + * \brief Compiles a component from the WebAssembly text format. + * + * This function will automatically use `wat2wasm` on the input and then + * delegate to the #compile function. + */ + static Result compile(Engine &engine, std::string_view wat) { + auto wasm = wat2wasm(wat); + if (!wasm) { + return wasm.err(); + } + auto bytes = wasm.ok(); + return compile(engine, bytes); + } + + /** + * \brief Compiles a component from the WebAssembly binary format. + * + * This function compiles the provided WebAssembly binary specified by `wasm` + * within the compilation settings configured by `engine`. This method is + * synchronous and will not return until the component has finished compiling. + * + * This function can fail if the WebAssembly binary is invalid or doesn't + * validate (or similar). Note that this API does not compile WebAssembly + * modules, which is done with `Module` instead of `Component`. + */ + static Result compile(Engine &engine, Span wasm) { + wasmtime_component_t *ret = nullptr; + auto *error = + wasmtime_component_new(engine.capi(), wasm.data(), wasm.size(), &ret); + if (error != nullptr) { + return Error(error); + } + return Component(ret); + } +#endif // WASMTIME_FEATURE_COMPILER + + /** + * \brief Deserializes a previous list of bytes created with `serialize`. + * + * This function is intended to be much faster than `compile` where it uses + * the artifacts of a previous compilation to quickly create an in-memory + * component ready for instantiation. + * + * It is not safe to pass arbitrary input to this function, it is only safe to + * pass in output from previous calls to `serialize`. For more information see + * the Rust documentation - + * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize + */ + static Result deserialize(Engine &engine, Span wasm) { + wasmtime_component_t *ret = nullptr; + auto *error = wasmtime_component_deserialize(engine.capi(), wasm.data(), + wasm.size(), &ret); + if (error != nullptr) { + return Error(error); + } + return Component(ret); + } + + /** + * \brief Deserializes a component from an on-disk file. + * + * This function is the same as `deserialize` except that it reads the data + * for the serialized component from the path on disk. This can be faster than + * the alternative which may require copying the data around. + * + * It is not safe to pass arbitrary input to this function, it is only safe to + * pass in output from previous calls to `serialize`. For more information see + * the Rust documentation - + * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize + */ + static Result deserialize_file(Engine &engine, + const std::string &path) { + wasmtime_component_t *ret = nullptr; + auto *error = + wasmtime_component_deserialize_file(engine.capi(), path.c_str(), &ret); + if (error != nullptr) { + return Error(error); + } + return Component(ret); + } + +#ifdef WASMTIME_FEATURE_COMPILER + /** + * \brief Serializes this component to a list of bytes. + * + * The returned bytes can then be used to later pass to `deserialize` to + * quickly recreate this component in a different process perhaps. + */ + Result> serialize() const { + wasm_byte_vec_t bytes; + auto *error = wasmtime_component_serialize(ptr.get(), &bytes); + if (error != nullptr) { + return Error(error); + } + std::vector ret; + Span raw(reinterpret_cast(bytes.data), bytes.size); + ret.assign(raw.begin(), raw.end()); + wasm_byte_vec_delete(&bytes); + return ret; + } +#endif // WASMTIME_FEATURE_COMPILER + + /** + * \brief Returns the export index for the export named `name` in this + * component. + * + * The `instance` argument is an optionally provided index which is the + * instance under which the `name` should be looked up. + */ + std::optional export_index(ExportIndex *instance, + std::string_view name) { + auto ret = wasmtime_component_get_export_index( + capi(), instance ? instance->capi() : nullptr, name.data(), + name.size()); + if (ret) { + return ExportIndex(ret); + } + return std::nullopt; + }; +}; + +} // namespace component +} // namespace wasmtime + +#endif // WASMTIME_FEATURE_COMPONENT_MODEL + +#endif // WASMTIME_COMPONENT_HH diff --git a/crates/c-api/include/wasmtime/engine.hh b/crates/c-api/include/wasmtime/engine.hh index a482367cfd06..eab2137e273b 100644 --- a/crates/c-api/include/wasmtime/engine.hh +++ b/crates/c-api/include/wasmtime/engine.hh @@ -56,6 +56,12 @@ public: /// \brief Returns whether this engine is using Pulley for execution. void is_pulley() const { wasmtime_engine_is_pulley(ptr.get()); } + + /// \brief Returns the underlying C API pointer. + const wasm_engine_t *capi() const { return ptr.get(); } + + /// \brief Returns the underlying C API pointer. + wasm_engine_t *capi() { return ptr.get(); } }; } // namespace wasmtime diff --git a/crates/c-api/include/wasmtime/func.hh b/crates/c-api/include/wasmtime/func.hh index 4de28a153d46..1dc4e05356ec 100644 --- a/crates/c-api/include/wasmtime/func.hh +++ b/crates/c-api/include/wasmtime/func.hh @@ -108,7 +108,7 @@ template <> struct WasmType> { return std::nullopt; } wasmtime_externref_t val; - wasmtime_externref_from_raw(cx.raw_context(), p->externref, &val); + wasmtime_externref_from_raw(cx.capi(), p->externref, &val); return ExternRef(val); } }; @@ -618,7 +618,7 @@ public: ptr = reinterpret_cast(alignof(wasmtime_val_raw_t)); WasmTypeList::store(cx, ptr, params); wasm_trap_t *trap = nullptr; - auto *error = wasmtime_func_call_unchecked(cx.raw_context(), &f.func, ptr, + auto *error = wasmtime_func_call_unchecked(cx.capi(), &f.func, ptr, storage.size(), &trap); if (error != nullptr) { return TrapError(Error(error)); @@ -666,7 +666,7 @@ template <> struct detail::WasmType> { static void store(Store::Context cx, wasmtime_val_raw_t *p, const std::optional func) { if (func) { - p->funcref = wasmtime_func_to_raw(cx.raw_context(), &func->capi()); + p->funcref = wasmtime_func_to_raw(cx.capi(), &func->capi()); } else { p->funcref = 0; } @@ -677,7 +677,7 @@ template <> struct detail::WasmType> { return std::nullopt; } wasmtime_func_t ret; - wasmtime_func_from_raw(cx.raw_context(), p->funcref, &ret); + wasmtime_func_from_raw(cx.capi(), p->funcref, &ret); return ret; } }; diff --git a/crates/c-api/include/wasmtime/module.hh b/crates/c-api/include/wasmtime/module.hh index 292f11468781..e3edccd91e53 100644 --- a/crates/c-api/include/wasmtime/module.hh +++ b/crates/c-api/include/wasmtime/module.hh @@ -183,6 +183,12 @@ public: return ret; } #endif // WASMTIME_FEATURE_COMPILER + + /// \brief Returns the underlying C API pointer. + const wasmtime_module_t *capi() const { return ptr.get(); } + + /// \brief Returns the underlying C API pointer. + wasmtime_module_t *capi() { return ptr.get(); } }; } // namespace wasmtime diff --git a/crates/c-api/include/wasmtime/store.hh b/crates/c-api/include/wasmtime/store.hh index 00ae9b865b27..a0830a5ffbd7 100644 --- a/crates/c-api/include/wasmtime/store.hh +++ b/crates/c-api/include/wasmtime/store.hh @@ -149,8 +149,11 @@ public: wasmtime_context_set_epoch_deadline(ptr, ticks_beyond_current); } - /// Returns the raw context pointer for the C API. - wasmtime_context_t *raw_context() { return ptr; } + /// \brief Returns the underlying C API pointer. + const wasmtime_context_t *capi() const { return ptr; } + + /// \brief Returns the underlying C API pointer. + wasmtime_context_t *capi() { return ptr; } }; /// \brief Provides limits for a store. Used by hosts to limit resource @@ -195,6 +198,12 @@ public: /// Runs a garbage collection pass in the referenced store to collect loose /// GC-managed objects, if any are available. void gc() { context().gc(); } + + /// \brief Returns the underlying C API pointer. + const wasmtime_store_t *capi() const { return ptr.get(); } + + /// \brief Returns the underlying C API pointer. + wasmtime_store_t *capi() { return ptr.get(); } }; } // namespace wasmtime diff --git a/crates/c-api/include/wasmtime/val.hh b/crates/c-api/include/wasmtime/val.hh index 6e0b692e95b0..5902042dff4b 100644 --- a/crates/c-api/include/wasmtime/val.hh +++ b/crates/c-api/include/wasmtime/val.hh @@ -88,14 +88,14 @@ public: /// Consumes ownership of the underlying `wasmtime_externref_t` and returns /// the result of `wasmtime_externref_to_raw`. uint32_t take_raw(Store::Context cx) { - uint32_t ret = wasmtime_externref_to_raw(cx.raw_context(), &val); + uint32_t ret = wasmtime_externref_to_raw(cx.capi(), &val); wasmtime_externref_set_null(&val); return ret; } /// Returns `wasmtime_externref_to_raw`. uint32_t borrow_raw(Store::Context cx) const { - return wasmtime_externref_to_raw(cx.raw_context(), &val); + return wasmtime_externref_to_raw(cx.capi(), &val); } }; @@ -148,14 +148,14 @@ public: /// Consumes ownership of the underlying `wasmtime_anyref_t` and returns the /// result of `wasmtime_anyref_to_raw`. uint32_t take_raw(Store::Context cx) { - uint32_t ret = wasmtime_anyref_to_raw(cx.raw_context(), &val); + uint32_t ret = wasmtime_anyref_to_raw(cx.capi(), &val); wasmtime_anyref_set_null(&val); return ret; } /// Returns `wasmtime_anyref_to_raw`. uint32_t borrow_raw(Store::Context cx) const { - return wasmtime_anyref_to_raw(cx.raw_context(), &val); + return wasmtime_anyref_to_raw(cx.capi(), &val); } /// \brief If this is an `i31`, get the value zero-extended. diff --git a/crates/c-api/src/component/component.rs b/crates/c-api/src/component/component.rs index ff1eb08f27c6..9cafd3ba33f0 100644 --- a/crates/c-api/src/component/component.rs +++ b/crates/c-api/src/component/component.rs @@ -115,6 +115,15 @@ pub unsafe extern "C" fn wasmtime_component_get_export_index( .map(|export_index| Box::new(wasmtime_component_export_index_t { export_index })) } +#[unsafe(no_mangle)] +pub unsafe extern "C" fn wasmtime_component_export_index_clone( + export_index: &wasmtime_component_export_index_t, +) -> Box { + Box::new(wasmtime_component_export_index_t { + export_index: export_index.export_index, + }) +} + #[unsafe(no_mangle)] pub unsafe extern "C" fn wasmtime_component_export_index_delete( _export_index: Box, diff --git a/crates/c-api/tests/component/call_func.cc b/crates/c-api/tests/component/call_func.cc index 011fd6aa826c..c670fc615496 100644 --- a/crates/c-api/tests/component/call_func.cc +++ b/crates/c-api/tests/component/call_func.cc @@ -3,6 +3,11 @@ #include #include #include +#include +#include + +using namespace wasmtime; +using namespace wasmtime::component; TEST(component, call_func) { static constexpr auto component_text = std::string_view{ @@ -21,35 +26,23 @@ TEST(component, call_func) { ) )END", }; - const auto engine = wasm_engine_new(); - EXPECT_NE(engine, nullptr); - - const auto store = wasmtime_store_new(engine, nullptr, nullptr); - const auto context = wasmtime_store_context(store); - - wasmtime_component_t *component = nullptr; - - auto err = wasmtime_component_new( - engine, reinterpret_cast(component_text.data()), - component_text.size(), &component); - CHECK_ERR(err); - - const auto f = - wasmtime_component_get_export_index(component, nullptr, "f", 1); + Engine engine; + Store store(engine); + auto context = store.context(); + auto component = Component::compile(engine, component_text).unwrap(); + auto f = *component.export_index(nullptr, "f"); - EXPECT_NE(f, nullptr); - - const auto linker = wasmtime_component_linker_new(engine); + const auto linker = wasmtime_component_linker_new(engine.capi()); wasmtime_component_instance_t instance = {}; - err = wasmtime_component_linker_instantiate(linker, context, component, - &instance); + auto err = wasmtime_component_linker_instantiate(linker, context.capi(), + component.capi(), &instance); CHECK_ERR(err); wasmtime_component_func_t func = {}; - const auto found = - wasmtime_component_instance_get_func(&instance, context, f, &func); + const auto found = wasmtime_component_instance_get_func( + &instance, context.capi(), f.capi(), &func); EXPECT_TRUE(found); auto params = std::array{ @@ -65,21 +58,16 @@ TEST(component, call_func) { auto results = std::array{}; - err = - wasmtime_component_func_call(&func, context, params.data(), params.size(), - results.data(), results.size()); + err = wasmtime_component_func_call(&func, context.capi(), params.data(), + params.size(), results.data(), + results.size()); CHECK_ERR(err); - err = wasmtime_component_func_post_return(&func, context); + err = wasmtime_component_func_post_return(&func, context.capi()); CHECK_ERR(err); EXPECT_EQ(results[0].kind, WASMTIME_COMPONENT_U32); EXPECT_EQ(results[0].of.u32, 69); - wasmtime_component_export_index_delete(f); wasmtime_component_linker_delete(linker); - wasmtime_component_delete(component); - - wasmtime_store_delete(store); - wasm_engine_delete(engine); } diff --git a/crates/c-api/tests/component/define_module.cc b/crates/c-api/tests/component/define_module.cc index 537e305d55f5..1049f4e0f6df 100644 --- a/crates/c-api/tests/component/define_module.cc +++ b/crates/c-api/tests/component/define_module.cc @@ -2,6 +2,12 @@ #include #include +#include +#include +#include + +using namespace wasmtime; +using namespace wasmtime::component; TEST(component, define_module) { static constexpr auto module_wat = std::string_view{ @@ -25,55 +31,34 @@ TEST(component, define_module) { ) )END", }; - const auto engine = wasm_engine_new(); - EXPECT_NE(engine, nullptr); - - wasm_byte_vec_t wasm; - auto err = wasmtime_wat2wasm(module_wat.data(), module_wat.size(), &wasm); - CHECK_ERR(err); - - wasmtime_module_t *module = nullptr; - err = wasmtime_module_new( - engine, reinterpret_cast(wasm.data), wasm.size, &module); - CHECK_ERR(err); - wasm_byte_vec_delete(&wasm); - const auto store = wasmtime_store_new(engine, nullptr, nullptr); - const auto context = wasmtime_store_context(store); + Engine engine; + Module module = Module::compile(engine, module_wat).unwrap(); + Store store(engine); + auto context = store.context(); - wasmtime_component_t *component = nullptr; + Component component = Component::compile(engine, component_text).unwrap(); - err = wasmtime_component_new( - engine, reinterpret_cast(component_text.data()), - component_text.size(), &component); - - CHECK_ERR(err); - - const auto linker = wasmtime_component_linker_new(engine); + const auto linker = wasmtime_component_linker_new(engine.capi()); const auto root = wasmtime_component_linker_root(linker); wasmtime_component_linker_instance_t *x_y_z = nullptr; - err = wasmtime_component_linker_instance_add_instance( + auto err = wasmtime_component_linker_instance_add_instance( root, "x:y/z", strlen("x:y/z"), &x_y_z); CHECK_ERR(err); - err = wasmtime_component_linker_instance_add_module(x_y_z, "mod", - strlen("mod"), module); + err = wasmtime_component_linker_instance_add_module( + x_y_z, "mod", strlen("mod"), module.capi()); CHECK_ERR(err); wasmtime_component_linker_instance_delete(x_y_z); wasmtime_component_linker_instance_delete(root); wasmtime_component_instance_t instance = {}; - err = wasmtime_component_linker_instantiate(linker, context, component, - &instance); + err = wasmtime_component_linker_instantiate(linker, context.capi(), + component.capi(), &instance); CHECK_ERR(err); wasmtime_component_linker_delete(linker); - wasmtime_component_delete(component); - wasmtime_module_delete(module); - - wasmtime_store_delete(store); - wasm_engine_delete(engine); } diff --git a/crates/c-api/tests/component/instantiate.cc b/crates/c-api/tests/component/instantiate.cc index a08ef577bd14..c3a8ada55e90 100644 --- a/crates/c-api/tests/component/instantiate.cc +++ b/crates/c-api/tests/component/instantiate.cc @@ -2,6 +2,11 @@ #include #include +#include +#include + +using namespace wasmtime; +using namespace wasmtime::component; TEST(component, instantiate) { static constexpr auto bytes = std::string_view{ @@ -12,34 +17,19 @@ TEST(component, instantiate) { )END", }; - const auto engine = wasm_engine_new(); - EXPECT_NE(engine, nullptr); - - const auto store = wasmtime_store_new(engine, nullptr, nullptr); - EXPECT_NE(store, nullptr); - const auto context = wasmtime_store_context(store); - EXPECT_NE(context, nullptr); - - wasmtime_component_t *component = nullptr; - - auto error = wasmtime_component_new( - engine, reinterpret_cast(bytes.data()), bytes.size(), - &component); + Engine engine; + Store store(engine); + auto context = store.context(); + Component component = Component::compile(engine, bytes).unwrap(); - CHECK_ERR(error); - - const auto linker = wasmtime_component_linker_new(engine); + const auto linker = wasmtime_component_linker_new(engine.capi()); EXPECT_NE(linker, nullptr); wasmtime_component_instance_t instance = {}; - error = wasmtime_component_linker_instantiate(linker, context, component, - &instance); + auto error = wasmtime_component_linker_instantiate( + linker, context.capi(), component.capi(), &instance); CHECK_ERR(error); wasmtime_component_linker_delete(linker); - wasmtime_component_delete(component); - - wasmtime_store_delete(store); - wasm_engine_delete(engine); } diff --git a/crates/c-api/tests/component/lookup_func.cc b/crates/c-api/tests/component/lookup_func.cc index b3990cd8386e..250903d9c0b9 100644 --- a/crates/c-api/tests/component/lookup_func.cc +++ b/crates/c-api/tests/component/lookup_func.cc @@ -2,6 +2,11 @@ #include #include +#include +#include + +using namespace wasmtime; +using namespace wasmtime::component; TEST(component, lookup_func) { static constexpr auto component_text = std::string_view{ @@ -16,52 +21,36 @@ TEST(component, lookup_func) { ) )END", }; - const auto engine = wasm_engine_new(); - EXPECT_NE(engine, nullptr); - - const auto store = wasmtime_store_new(engine, nullptr, nullptr); - const auto context = wasmtime_store_context(store); - - wasmtime_component_t *component = nullptr; - - auto err = wasmtime_component_new( - engine, reinterpret_cast(component_text.data()), - component_text.size(), &component); - CHECK_ERR(err); - - auto f = wasmtime_component_get_export_index(component, nullptr, "ff", - strlen("ff")); + Engine engine; + Store store(engine); + auto context = store.context(); + Component component = Component::compile(engine, component_text).unwrap(); + auto f = component.export_index(nullptr, "ff"); - EXPECT_EQ(f, nullptr); + EXPECT_FALSE(f); - f = wasmtime_component_get_export_index(component, nullptr, "f", strlen("f")); + f = component.export_index(nullptr, "f"); - EXPECT_NE(f, nullptr); + EXPECT_TRUE(f); - const auto linker = wasmtime_component_linker_new(engine); + const auto linker = wasmtime_component_linker_new(engine.capi()); wasmtime_component_instance_t instance = {}; - err = wasmtime_component_linker_instantiate(linker, context, component, - &instance); + auto err = wasmtime_component_linker_instantiate(linker, context.capi(), + component.capi(), &instance); CHECK_ERR(err); wasmtime_component_func_t func = {}; - const auto found = - wasmtime_component_instance_get_func(&instance, context, f, &func); + const auto found = wasmtime_component_instance_get_func( + &instance, context.capi(), f->capi(), &func); EXPECT_TRUE(found); EXPECT_NE(func.store_id, 0); - wasmtime_component_export_index_delete(f); + auto f2 = wasmtime_component_instance_get_export_index( + &instance, context.capi(), nullptr, "f", strlen("f")); + EXPECT_NE(f2, nullptr); - f = wasmtime_component_instance_get_export_index(&instance, context, nullptr, - "f", strlen("f")); - EXPECT_NE(f, nullptr); - - wasmtime_component_export_index_delete(f); + wasmtime_component_export_index_delete(f2); wasmtime_component_linker_delete(linker); - wasmtime_component_delete(component); - - wasmtime_store_delete(store); - wasm_engine_delete(engine); } diff --git a/crates/c-api/tests/component/values.cc b/crates/c-api/tests/component/values.cc index 2a5c686a154a..282b08985b7b 100644 --- a/crates/c-api/tests/component/values.cc +++ b/crates/c-api/tests/component/values.cc @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include @@ -9,6 +11,9 @@ #include #include +using namespace wasmtime; +using namespace wasmtime::component; + static std::string echo_component(std::string_view type, std::string_view func, std::string_view host_params) { return std::format( @@ -53,10 +58,10 @@ static std::string echo_component(std::string_view type, std::string_view func, } struct Context { - wasm_engine_t *engine; - wasmtime_store_t *store; + Engine engine; + Store store; wasmtime_context_t *context; - wasmtime_component_t *component; + Component component; wasmtime_component_instance_t instance; wasmtime_component_func_t func; }; @@ -65,26 +70,16 @@ static Context create(std::string_view type, std::string_view body, std::string_view host_params, wasmtime_component_func_callback_t callback) { auto component_text = echo_component(type, body, host_params); - const auto engine = wasm_engine_new(); - EXPECT_NE(engine, nullptr); - - const auto store = wasmtime_store_new(engine, nullptr, nullptr); - const auto context = wasmtime_store_context(store); - - wasmtime_component_t *component = nullptr; + Engine engine; + Store store(engine); + const auto context = store.context().capi(); + Component component = Component::compile(engine, component_text).unwrap(); - auto err = wasmtime_component_new( - engine, reinterpret_cast(component_text.data()), - component_text.size(), &component); - - CHECK_ERR(err); + auto f = component.export_index(nullptr, "call"); - auto f = wasmtime_component_get_export_index(component, nullptr, "call", - strlen("call")); + EXPECT_TRUE(f); - EXPECT_NE(f, nullptr); - - const auto linker = wasmtime_component_linker_new(engine); + const auto linker = wasmtime_component_linker_new(engine.capi()); const auto root = wasmtime_component_linker_root(linker); wasmtime_component_linker_instance_add_func(root, "do", strlen("do"), @@ -93,23 +88,21 @@ static Context create(std::string_view type, std::string_view body, wasmtime_component_linker_instance_delete(root); wasmtime_component_instance_t instance = {}; - err = wasmtime_component_linker_instantiate(linker, context, component, - &instance); + auto err = wasmtime_component_linker_instantiate(linker, context, + component.capi(), &instance); CHECK_ERR(err); wasmtime_component_linker_delete(linker); wasmtime_component_func_t func = {}; - const auto found = - wasmtime_component_instance_get_func(&instance, context, f, &func); + const auto found = wasmtime_component_instance_get_func(&instance, context, + f->capi(), &func); EXPECT_TRUE(found); EXPECT_NE(func.store_id, 0); - wasmtime_component_export_index_delete(f); - return Context{ .engine = engine, - .store = store, + .store = std::move(store), .context = context, .component = component, .instance = instance, @@ -117,12 +110,6 @@ static Context create(std::string_view type, std::string_view body, }; } -static void destroy(Context &ctx) { - wasmtime_component_delete(ctx.component); - wasmtime_store_delete(ctx.store); - wasm_engine_delete(ctx.engine); -} - TEST(component, value_record) { static const auto check = [](const wasmtime_component_val_t &val, uint64_t x, uint64_t y) { @@ -205,8 +192,6 @@ local.get $res wasmtime_component_val_delete(&arg); wasmtime_component_val_delete(&res); - - destroy(ctx); } TEST(component, value_string) { @@ -271,8 +256,6 @@ local.get $res wasmtime_component_val_delete(&arg); wasmtime_component_val_delete(&res); - - destroy(ctx); } TEST(component, value_list) { @@ -349,8 +332,6 @@ local.get $res wasmtime_component_val_delete(&arg); wasmtime_component_val_delete(&res); - - destroy(ctx); } TEST(component, value_tuple) { @@ -429,8 +410,6 @@ local.get $res wasmtime_component_val_delete(&arg); wasmtime_component_val_delete(&res); - - destroy(ctx); } TEST(component, value_variant) { @@ -543,8 +522,6 @@ local.get $res wasmtime_component_val_delete(&arg); wasmtime_component_val_delete(&res); - - destroy(ctx); } TEST(component, value_enum) { @@ -601,8 +578,6 @@ call $do wasmtime_component_val_delete(&arg); wasmtime_component_val_delete(&res); - - destroy(ctx); } TEST(component, value_option) { @@ -681,8 +656,6 @@ local.get $res wasmtime_component_val_delete(&arg); wasmtime_component_val_delete(&res); - - destroy(ctx); } TEST(component, value_result) { @@ -759,8 +732,6 @@ local.get $res wasmtime_component_val_delete(&arg); wasmtime_component_val_delete(&res); - - destroy(ctx); } TEST(component, value_flags) { @@ -823,8 +794,6 @@ call $do wasmtime_component_val_delete(&arg); wasmtime_component_val_delete(&res); - - destroy(ctx); } TEST(component, value_list_inner) { diff --git a/crates/c-api/tests/wasip2.cc b/crates/c-api/tests/wasip2.cc index c5a61307f4e6..bc3b3a535518 100644 --- a/crates/c-api/tests/wasip2.cc +++ b/crates/c-api/tests/wasip2.cc @@ -2,6 +2,11 @@ #include #include +#include +#include + +using namespace wasmtime; +using namespace wasmtime::component; TEST(wasip2, smoke) { static constexpr auto component_text = std::string_view{ @@ -9,39 +14,28 @@ TEST(wasip2, smoke) { (component) )END", }; - const auto engine = wasm_engine_new(); - EXPECT_NE(engine, nullptr); - const auto store = wasmtime_store_new(engine, nullptr, nullptr); - const auto context = wasmtime_store_context(store); + Engine engine; + Store store(engine); + auto context = store.context(); const auto cfg = wasmtime_wasip2_config_new(); wasmtime_wasip2_config_inherit_stdin(cfg); wasmtime_wasip2_config_inherit_stdout(cfg); wasmtime_wasip2_config_inherit_stderr(cfg); wasmtime_wasip2_config_arg(cfg, "hello", strlen("hello")); - wasmtime_context_set_wasip2(context, cfg); - - wasmtime_component_t *component = nullptr; + wasmtime_context_set_wasip2(context.capi(), cfg); - auto err = wasmtime_component_new( - engine, reinterpret_cast(component_text.data()), - component_text.size(), &component); + Component component = Component::compile(engine, component_text).unwrap(); - CHECK_ERR(err); - - const auto linker = wasmtime_component_linker_new(engine); + const auto linker = wasmtime_component_linker_new(engine.capi()); wasmtime_component_linker_add_wasip2(linker); wasmtime_component_instance_t instance = {}; - err = wasmtime_component_linker_instantiate(linker, context, component, - &instance); + auto err = wasmtime_component_linker_instantiate(linker, context.capi(), + component.capi(), &instance); CHECK_ERR(err); wasmtime_component_linker_delete(linker); - wasmtime_component_delete(component); - - wasmtime_store_delete(store); - wasm_engine_delete(engine); }