Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 83 additions & 18 deletions crates/c-api/include/wasmtime/component/types/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,23 @@ size_t wasmtime_component_type_import_count(const wasmtime_component_type_t *ty,

/// \brief Retrieves the import with the specified name.
///
/// The returned `wasmtime_component_item_t` must be deallocated with
/// `wasmtime_component_item_delete`.
/// The returned `wasmtime_component_extern_t` must be deallocated with
/// `wasmtime_component_extern_delete`.
WASM_API_EXTERN
bool wasmtime_component_type_import_get(const wasmtime_component_type_t *ty,
const wasm_engine_t *engine,
const char *name, size_t name_len,
struct wasmtime_component_item_t *ret);
bool wasmtime_component_type_import_get(
const wasmtime_component_type_t *ty, const wasm_engine_t *engine,
const char *name, size_t name_len,
struct wasmtime_component_extern_t **ret);

/// \brief Retrieves the nth import.
///
/// The returned `wasmtime_component_item_t` must be deallocated with
/// `wasmtime_component_item_delete`.
/// The returned `wasmtime_component_extern_t` must be deallocated with
/// `wasmtime_component_extern_delete`.
WASM_API_EXTERN
bool wasmtime_component_type_import_nth(
const wasmtime_component_type_t *ty, const wasm_engine_t *engine,
size_t nth, const char **name_ret, size_t *name_len_ret,
struct wasmtime_component_item_t *type_ret);
struct wasmtime_component_extern_t **ret);

/// \brief Returns the number of exports of a component type.
WASM_API_EXTERN
Expand All @@ -65,23 +65,23 @@ size_t wasmtime_component_type_export_count(const wasmtime_component_type_t *ty,

/// \brief Retrieves the export with the specified name.
///
/// The returned `wasmtime_component_item_t` must be deallocated with
/// `wasmtime_component_item_delete`.
/// The returned `wasmtime_component_extern_t` must be deallocated with
/// `wasmtime_component_extern_delete`.
WASM_API_EXTERN
bool wasmtime_component_type_export_get(const wasmtime_component_type_t *ty,
const wasm_engine_t *engine,
const char *name, size_t name_len,
struct wasmtime_component_item_t *ret);
bool wasmtime_component_type_export_get(
const wasmtime_component_type_t *ty, const wasm_engine_t *engine,
const char *name, size_t name_len,
struct wasmtime_component_extern_t **ret);

/// \brief Retrieves the nth export.
///
/// The returned `wasmtime_component_item_t` must be deallocated with
/// `wasmtime_component_item_delete`.
/// The returned `wasmtime_component_extern_t` must be deallocated with
/// `wasmtime_component_extern_delete`.
WASM_API_EXTERN
bool wasmtime_component_type_export_nth(
const wasmtime_component_type_t *ty, const wasm_engine_t *engine,
size_t nth, const char **name_ret, size_t *name_len_ret,
struct wasmtime_component_item_t *type_ret);
struct wasmtime_component_extern_t **ret);

/// \brief Value of #wasmtime_component_item_kind_t meaning that
/// #wasmtime_component_item_t is a component.
Expand Down Expand Up @@ -153,6 +153,71 @@ void wasmtime_component_item_clone(const wasmtime_component_item_t *item,
WASM_API_EXTERN
void wasmtime_component_item_delete(wasmtime_component_item_t *ptr);

/// \brief Full description of a single component or component instance export
/// or import.
///
/// This carries the type of the item being imported or exported along with
/// any metadata attached to it such as `(implements "...")` or
/// `(external-id "...")` annotations.
///
/// Note that this structure contains pointers to the original component or
/// instance type that it's acquired from. This must always be
/// destroyed/accessed before those original types are destroyed.
typedef struct wasmtime_component_extern_t wasmtime_component_extern_t;

/// \brief Clones a component extern.
///
/// The returned pointer must be deallocated with
/// `wasmtime_component_extern_delete`.
///
/// Note that this does not clone the internal pointers that the
/// `wasmtime_component_extern_t` struct refers to, so the returned structure
/// still cannot outlive the original source that this comes from.
WASM_API_EXTERN
wasmtime_component_extern_t *
wasmtime_component_extern_clone(const wasmtime_component_extern_t *e);

/// \brief Returns the type of the item that this import/export refers to.
///
/// The returned `wasmtime_component_item_t` must be deallocated with
/// `wasmtime_component_item_delete`.
WASM_API_EXTERN
void wasmtime_component_extern_type(const wasmtime_component_extern_t *e,
wasmtime_component_item_t *ret);

/// \brief Returns the `implements` attribute of this import/export.
///
/// Returns `NULL` if this isn't present. Writes the length of the return value
/// to `len`. The returned pointer cannot be used outside the lifetime of `e`.
WASM_API_EXTERN
const char *
wasmtime_component_extern_implements(const wasmtime_component_extern_t *e,
size_t *len);

/// \brief Returns whether this import/export `e` has an `implements` attribute
/// which matches the `name` provided (which is `len` bytes long).
///
/// This returns `false` if `e` has no `implements` attribute. Otherwise this
/// returns `true` if the attribute is exactly equal to `name` or if it's a
/// semver-compatible version of `name`. For example `(implements
/// "a:b/c@1.1.0")` matches both `a:b/c@1.0.0` and `a:b/c@1.2.0`.
WASM_API_EXTERN
bool wasmtime_component_extern_is_implements(
const wasmtime_component_extern_t *e, const char *name, size_t len);

/// \brief Returns the `external-id` attribute of this import/export.
///
/// Returns `NULL` if this isn't present. Writes the length of the return value
/// to `len`. The returned pointer cannot be used outside the lifetime of `e`.
WASM_API_EXTERN
const char *
wasmtime_component_extern_external_id(const wasmtime_component_extern_t *e,
size_t *len);

/// \brief Deallocates a component extern.
WASM_API_EXTERN
void wasmtime_component_extern_delete(wasmtime_component_extern_t *ptr);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
125 changes: 99 additions & 26 deletions crates/c-api/include/wasmtime/component/types/component.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace wasmtime {
namespace component {

class ComponentItem;
class ComponentExtern;

/**
* \brief Represents the type of a WebAssembly component.
Expand All @@ -35,11 +36,17 @@ class ComponentType {
}

/// Retrieves the import with the specified name.
std::optional<ComponentItem> import_get(const Engine &engine,
std::string_view name) const;
///
/// The returned `ComponentExtern` borrows from this type and the engine and
/// must not outlive either of them.
std::optional<ComponentExtern> import_get(const Engine &engine,
std::string_view name) const;

/// Retrieves the nth import.
std::optional<std::pair<std::string_view, ComponentItem>>
///
/// The returned `ComponentExtern` borrows from this type and the engine and
/// must not outlive either of them.
std::optional<std::pair<std::string_view, ComponentExtern>>
import_nth(const Engine &engine, size_t nth) const;

/// Returns the number of exports of this component type.
Expand All @@ -48,11 +55,17 @@ class ComponentType {
}

/// Retrieves the export with the specified name.
std::optional<ComponentItem> export_get(const Engine &engine,
std::string_view name) const;
///
/// The returned `ComponentExtern` borrows from this type and the engine and
/// must not outlive either of them.
std::optional<ComponentExtern> export_get(const Engine &engine,
std::string_view name) const;

/// Retrieves the nth export.
std::optional<std::pair<std::string_view, ComponentItem>>
///
/// The returned `ComponentExtern` borrows from this type and the engine and
/// must not outlive either of them.
std::optional<std::pair<std::string_view, ComponentExtern>>
export_nth(const Engine &engine, size_t nth) const;
};

Expand Down Expand Up @@ -170,6 +183,59 @@ public:
const ValType &type() const;
};

/**
* \brief Full description of a single import or export of a component or a
* component instance.
*
* This carries the type of the item being imported or exported along with any
* `(implements "...")` or `(external-id "...")` annotations attached to it.
*
* Note that this borrows string data from the `ComponentType` or
* `ComponentInstanceType` it was acquired from (and the `Engine` used to
* acquire it), so it must not outlive either of those. Copies of this class
* share the same borrow and are subject to the same restriction.
*/
class ComponentExtern {
WASMTIME_CLONE_WRAPPER(ComponentExtern, wasmtime_component_extern);

/// Returns the type of the item that this import/export refers to.
ComponentItem type() const;

/// Returns the `(implements "...")` annotation of this import/export, if
/// present.
std::optional<std::string_view> implements() const {
size_t len = 0;
const char *ptr = wasmtime_component_extern_implements(capi(), &len);
if (ptr == nullptr) {
return std::nullopt;
}
return std::string_view(ptr, len);
}

/// Returns whether this import/export has an `(implements "...")`
/// annotation which is compatible with `name`.
///
/// This returns `false` if there is no `implements` annotation. Otherwise
/// this returns `true` if the annotation is exactly `name` or a
/// semver-compatible version of it, for example `a:b/c@1.1.0` matches
/// `a:b/c@1.0.0` and `a:b/c@1.2.0`.
bool is_implements(std::string_view name) const {
return wasmtime_component_extern_is_implements(capi(), name.data(),
name.size());
}

/// Returns the `(external-id "...")` annotation of this import/export, if
/// present.
std::optional<std::string_view> external_id() const {
size_t len = 0;
const char *ptr = wasmtime_component_extern_external_id(capi(), &len);
if (ptr == nullptr) {
return std::nullopt;
}
return std::string_view(ptr, len);
}
};

} // namespace component
} // namespace wasmtime

Expand All @@ -178,60 +244,67 @@ public:
#include <wasmtime/component/types/module.hh>
#include <wasmtime/component/types/val.hh>

inline std::optional<wasmtime::component::ComponentItem>
inline wasmtime::component::ComponentItem
wasmtime::component::ComponentExtern::type() const {
wasmtime_component_item_t item;
wasmtime_component_extern_type(capi(), &item);
return wasmtime::component::ComponentItem(std::move(item));
}

inline std::optional<wasmtime::component::ComponentExtern>
wasmtime::component::ComponentType::import_get(const wasmtime::Engine &engine,
std::string_view name) const {
wasmtime_component_item_t item;
bool found = wasmtime_component_type_import_get(
capi(), engine.capi(), name.data(), name.size(), &item);
wasmtime_component_extern_t *e;
bool found = wasmtime_component_type_import_get(capi(), engine.capi(),
name.data(), name.size(), &e);
if (!found) {
return std::nullopt;
}
return wasmtime::component::ComponentItem(std::move(item));
return wasmtime::component::ComponentExtern(e);
}

inline std::optional<
std::pair<std::string_view, wasmtime::component::ComponentItem>>
std::pair<std::string_view, wasmtime::component::ComponentExtern>>
wasmtime::component::ComponentType::import_nth(const wasmtime::Engine &engine,
size_t nth) const {
wasmtime_component_item_t item;
wasmtime_component_extern_t *e;
const char *name_data;
size_t name_size;
bool found = wasmtime_component_type_import_nth(
capi(), engine.capi(), nth, &name_data, &name_size, &item);
bool found = wasmtime_component_type_import_nth(capi(), engine.capi(), nth,
&name_data, &name_size, &e);
if (!found) {
return std::nullopt;
}
return std::make_pair(std::string_view(name_data, name_size),
wasmtime::component::ComponentItem(std::move(item)));
wasmtime::component::ComponentExtern(e));
}

inline std::optional<wasmtime::component::ComponentItem>
inline std::optional<wasmtime::component::ComponentExtern>
wasmtime::component::ComponentType::export_get(const wasmtime::Engine &engine,
std::string_view name) const {
wasmtime_component_item_t item;
bool found = wasmtime_component_type_export_get(
capi(), engine.capi(), name.data(), name.size(), &item);
wasmtime_component_extern_t *e;
bool found = wasmtime_component_type_export_get(capi(), engine.capi(),
name.data(), name.size(), &e);
if (!found) {
return std::nullopt;
}
return wasmtime::component::ComponentItem(std::move(item));
return wasmtime::component::ComponentExtern(e);
}

inline std::optional<
std::pair<std::string_view, wasmtime::component::ComponentItem>>
std::pair<std::string_view, wasmtime::component::ComponentExtern>>
wasmtime::component::ComponentType::export_nth(const wasmtime::Engine &engine,
size_t nth) const {
wasmtime_component_item_t item;
wasmtime_component_extern_t *e;
const char *name_data;
size_t name_size;
bool found = wasmtime_component_type_export_nth(
capi(), engine.capi(), nth, &name_data, &name_size, &item);
bool found = wasmtime_component_type_export_nth(capi(), engine.capi(), nth,
&name_data, &name_size, &e);
if (!found) {
return std::nullopt;
}
return std::make_pair(std::string_view(name_data, name_size),
wasmtime::component::ComponentItem(std::move(item)));
wasmtime::component::ComponentExtern(e));
}

inline const wasmtime::component::ComponentInstanceType &
Expand Down
15 changes: 8 additions & 7 deletions crates/c-api/include/wasmtime/component/types/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
extern "C" {
#endif

struct wasmtime_component_item_t;
struct wasmtime_component_extern_t;

/// \brief Represents the type of a component instance.
typedef struct wasmtime_component_instance_type
Expand All @@ -39,22 +39,23 @@ size_t wasmtime_component_instance_type_export_count(

/// \brief Retrieves the export with the specified name.
///
/// The returned `wasmtime_component_item_t` must be deallocated with
/// `wasmtime_component_item_delete`.
/// The returned `wasmtime_component_extern_t` must be deallocated with
/// `wasmtime_component_extern_delete`.
WASM_API_EXTERN
bool wasmtime_component_instance_type_export_get(
const wasmtime_component_instance_type_t *ty, const wasm_engine_t *engine,
const char *name, size_t name_len, struct wasmtime_component_item_t *ret);
const char *name, size_t name_len,
struct wasmtime_component_extern_t **ret);

/// \brief Retrieves the nth export.
///
/// The returned `wasmtime_component_item_t` must be deallocated with
/// `wasmtime_component_item_delete`.
/// The returned `wasmtime_component_extern_t` must be deallocated with
/// `wasmtime_component_extern_delete`.
WASM_API_EXTERN
bool wasmtime_component_instance_type_export_nth(
const wasmtime_component_instance_type_t *ty, const wasm_engine_t *engine,
size_t nth, const char **name_ret, size_t *name_len_ret,
struct wasmtime_component_item_t *type_ret);
struct wasmtime_component_extern_t **ret);

#ifdef __cplusplus
} // extern "C"
Expand Down
Loading
Loading