Skip to content

Commit 52356e0

Browse files
committed
Thread component-model-implements into the C API
Expose both the `Config` accessor plus API changes necessary to reflect over this proposal in the C API.
1 parent 2dc0124 commit 52356e0

10 files changed

Lines changed: 466 additions & 117 deletions

File tree

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

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,23 @@ size_t wasmtime_component_type_import_count(const wasmtime_component_type_t *ty,
4040

4141
/// \brief Retrieves the import with the specified name.
4242
///
43-
/// The returned `wasmtime_component_item_t` must be deallocated with
44-
/// `wasmtime_component_item_delete`.
43+
/// The returned `wasmtime_component_extern_t` must be deallocated with
44+
/// `wasmtime_component_extern_delete`.
4545
WASM_API_EXTERN
46-
bool wasmtime_component_type_import_get(const wasmtime_component_type_t *ty,
47-
const wasm_engine_t *engine,
48-
const char *name, size_t name_len,
49-
struct wasmtime_component_item_t *ret);
46+
bool wasmtime_component_type_import_get(
47+
const wasmtime_component_type_t *ty, const wasm_engine_t *engine,
48+
const char *name, size_t name_len,
49+
struct wasmtime_component_extern_t **ret);
5050

5151
/// \brief Retrieves the nth import.
5252
///
53-
/// The returned `wasmtime_component_item_t` must be deallocated with
54-
/// `wasmtime_component_item_delete`.
53+
/// The returned `wasmtime_component_extern_t` must be deallocated with
54+
/// `wasmtime_component_extern_delete`.
5555
WASM_API_EXTERN
5656
bool wasmtime_component_type_import_nth(
5757
const wasmtime_component_type_t *ty, const wasm_engine_t *engine,
5858
size_t nth, const char **name_ret, size_t *name_len_ret,
59-
struct wasmtime_component_item_t *type_ret);
59+
struct wasmtime_component_extern_t **ret);
6060

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

6666
/// \brief Retrieves the export with the specified name.
6767
///
68-
/// The returned `wasmtime_component_item_t` must be deallocated with
69-
/// `wasmtime_component_item_delete`.
68+
/// The returned `wasmtime_component_extern_t` must be deallocated with
69+
/// `wasmtime_component_extern_delete`.
7070
WASM_API_EXTERN
71-
bool wasmtime_component_type_export_get(const wasmtime_component_type_t *ty,
72-
const wasm_engine_t *engine,
73-
const char *name, size_t name_len,
74-
struct wasmtime_component_item_t *ret);
71+
bool wasmtime_component_type_export_get(
72+
const wasmtime_component_type_t *ty, const wasm_engine_t *engine,
73+
const char *name, size_t name_len,
74+
struct wasmtime_component_extern_t **ret);
7575

7676
/// \brief Retrieves the nth export.
7777
///
78-
/// The returned `wasmtime_component_item_t` must be deallocated with
79-
/// `wasmtime_component_item_delete`.
78+
/// The returned `wasmtime_component_extern_t` must be deallocated with
79+
/// `wasmtime_component_extern_delete`.
8080
WASM_API_EXTERN
8181
bool wasmtime_component_type_export_nth(
8282
const wasmtime_component_type_t *ty, const wasm_engine_t *engine,
8383
size_t nth, const char **name_ret, size_t *name_len_ret,
84-
struct wasmtime_component_item_t *type_ret);
84+
struct wasmtime_component_extern_t **ret);
8585

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

156+
/// \brief Full description of a single component or component instance export
157+
/// or import.
158+
///
159+
/// This carries the type of the item being imported or exported along with
160+
/// any metadata attached to it such as `(implements "...")` or
161+
/// `(external-id "...")` annotations.
162+
///
163+
/// Note that this structure contains pointers to the original component or
164+
/// instance type that it's acquired from. This must always be
165+
/// destroyed/accessed before those original types are destroyed.
166+
typedef struct wasmtime_component_extern_t wasmtime_component_extern_t;
167+
168+
/// \brief Clones a component extern.
169+
///
170+
/// The returned pointer must be deallocated with
171+
/// `wasmtime_component_extern_delete`.
172+
///
173+
/// Note that this does not clone the internal pointers that the
174+
/// `wasmtime_component_extern_t` struct refers to, so the returned structure
175+
/// still cannot outlive the original source that this comes from.
176+
WASM_API_EXTERN
177+
wasmtime_component_extern_t *
178+
wasmtime_component_extern_clone(const wasmtime_component_extern_t *e);
179+
180+
/// \brief Returns the type of the item that this import/export refers to.
181+
///
182+
/// The returned `wasmtime_component_item_t` must be deallocated with
183+
/// `wasmtime_component_item_delete`.
184+
WASM_API_EXTERN
185+
void wasmtime_component_extern_type(const wasmtime_component_extern_t *e,
186+
wasmtime_component_item_t *ret);
187+
188+
/// \brief Returns the `implements` attribute of this import/export.
189+
///
190+
/// Returns `NULL` if this isn't present. Writes the length of the return value
191+
/// to `len`. The returned pointer cannot be used outside the lifetime of `e`.
192+
WASM_API_EXTERN
193+
const char *
194+
wasmtime_component_extern_implements(const wasmtime_component_extern_t *e,
195+
size_t *len);
196+
197+
/// \brief Returns whether this import/export `e` has an `implements` attribute
198+
/// which matches the `name` provided (which is `len` bytes long).
199+
///
200+
/// This returns `false` if `e` has no `implements` attribute. Otherwise this
201+
/// returns `true` if the attribute is exactly equal to `name` or if it's a
202+
/// semver-compatible version of `name`. For example `(implements
203+
/// "a:b/c@1.1.0")` matches both `a:b/c@1.0.0` and `a:b/c@1.2.0`.
204+
WASM_API_EXTERN
205+
bool wasmtime_component_extern_is_implements(
206+
const wasmtime_component_extern_t *e, const char *name, size_t len);
207+
208+
/// \brief Returns the `external-id` attribute of this import/export.
209+
///
210+
/// Returns `NULL` if this isn't present. Writes the length of the return value
211+
/// to `len`. The returned pointer cannot be used outside the lifetime of `e`.
212+
WASM_API_EXTERN
213+
const char *
214+
wasmtime_component_extern_external_id(const wasmtime_component_extern_t *e,
215+
size_t *len);
216+
217+
/// \brief Deallocates a component extern.
218+
WASM_API_EXTERN
219+
void wasmtime_component_extern_delete(wasmtime_component_extern_t *ptr);
220+
156221
#ifdef __cplusplus
157222
} // extern "C"
158223
#endif

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

Lines changed: 99 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace wasmtime {
2222
namespace component {
2323

2424
class ComponentItem;
25+
class ComponentExtern;
2526

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

3738
/// Retrieves the import with the specified name.
38-
std::optional<ComponentItem> import_get(const Engine &engine,
39-
std::string_view name) const;
39+
///
40+
/// The returned `ComponentExtern` borrows from this type and the engine and
41+
/// must not outlive either of them.
42+
std::optional<ComponentExtern> import_get(const Engine &engine,
43+
std::string_view name) const;
4044

4145
/// Retrieves the nth import.
42-
std::optional<std::pair<std::string_view, ComponentItem>>
46+
///
47+
/// The returned `ComponentExtern` borrows from this type and the engine and
48+
/// must not outlive either of them.
49+
std::optional<std::pair<std::string_view, ComponentExtern>>
4350
import_nth(const Engine &engine, size_t nth) const;
4451

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

5057
/// Retrieves the export with the specified name.
51-
std::optional<ComponentItem> export_get(const Engine &engine,
52-
std::string_view name) const;
58+
///
59+
/// The returned `ComponentExtern` borrows from this type and the engine and
60+
/// must not outlive either of them.
61+
std::optional<ComponentExtern> export_get(const Engine &engine,
62+
std::string_view name) const;
5363

5464
/// Retrieves the nth export.
55-
std::optional<std::pair<std::string_view, ComponentItem>>
65+
///
66+
/// The returned `ComponentExtern` borrows from this type and the engine and
67+
/// must not outlive either of them.
68+
std::optional<std::pair<std::string_view, ComponentExtern>>
5669
export_nth(const Engine &engine, size_t nth) const;
5770
};
5871

@@ -170,6 +183,59 @@ public:
170183
const ValType &type() const;
171184
};
172185

186+
/**
187+
* \brief Full description of a single import or export of a component or a
188+
* component instance.
189+
*
190+
* This carries the type of the item being imported or exported along with any
191+
* `(implements "...")` or `(external-id "...")` annotations attached to it.
192+
*
193+
* Note that this borrows string data from the `ComponentType` or
194+
* `ComponentInstanceType` it was acquired from (and the `Engine` used to
195+
* acquire it), so it must not outlive either of those. Copies of this class
196+
* share the same borrow and are subject to the same restriction.
197+
*/
198+
class ComponentExtern {
199+
WASMTIME_CLONE_WRAPPER(ComponentExtern, wasmtime_component_extern);
200+
201+
/// Returns the type of the item that this import/export refers to.
202+
ComponentItem type() const;
203+
204+
/// Returns the `(implements "...")` annotation of this import/export, if
205+
/// present.
206+
std::optional<std::string_view> implements() const {
207+
size_t len = 0;
208+
const char *ptr = wasmtime_component_extern_implements(capi(), &len);
209+
if (ptr == nullptr) {
210+
return std::nullopt;
211+
}
212+
return std::string_view(ptr, len);
213+
}
214+
215+
/// Returns whether this import/export has an `(implements "...")`
216+
/// annotation which is compatible with `name`.
217+
///
218+
/// This returns `false` if there is no `implements` annotation. Otherwise
219+
/// this returns `true` if the annotation is exactly `name` or a
220+
/// semver-compatible version of it, for example `a:b/c@1.1.0` matches
221+
/// `a:b/c@1.0.0` and `a:b/c@1.2.0`.
222+
bool is_implements(std::string_view name) const {
223+
return wasmtime_component_extern_is_implements(capi(), name.data(),
224+
name.size());
225+
}
226+
227+
/// Returns the `(external-id "...")` annotation of this import/export, if
228+
/// present.
229+
std::optional<std::string_view> external_id() const {
230+
size_t len = 0;
231+
const char *ptr = wasmtime_component_extern_external_id(capi(), &len);
232+
if (ptr == nullptr) {
233+
return std::nullopt;
234+
}
235+
return std::string_view(ptr, len);
236+
}
237+
};
238+
173239
} // namespace component
174240
} // namespace wasmtime
175241

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

181-
inline std::optional<wasmtime::component::ComponentItem>
247+
inline wasmtime::component::ComponentItem
248+
wasmtime::component::ComponentExtern::type() const {
249+
wasmtime_component_item_t item;
250+
wasmtime_component_extern_type(capi(), &item);
251+
return wasmtime::component::ComponentItem(std::move(item));
252+
}
253+
254+
inline std::optional<wasmtime::component::ComponentExtern>
182255
wasmtime::component::ComponentType::import_get(const wasmtime::Engine &engine,
183256
std::string_view name) const {
184-
wasmtime_component_item_t item;
185-
bool found = wasmtime_component_type_import_get(
186-
capi(), engine.capi(), name.data(), name.size(), &item);
257+
wasmtime_component_extern_t *e;
258+
bool found = wasmtime_component_type_import_get(capi(), engine.capi(),
259+
name.data(), name.size(), &e);
187260
if (!found) {
188261
return std::nullopt;
189262
}
190-
return wasmtime::component::ComponentItem(std::move(item));
263+
return wasmtime::component::ComponentExtern(e);
191264
}
192265

193266
inline std::optional<
194-
std::pair<std::string_view, wasmtime::component::ComponentItem>>
267+
std::pair<std::string_view, wasmtime::component::ComponentExtern>>
195268
wasmtime::component::ComponentType::import_nth(const wasmtime::Engine &engine,
196269
size_t nth) const {
197-
wasmtime_component_item_t item;
270+
wasmtime_component_extern_t *e;
198271
const char *name_data;
199272
size_t name_size;
200-
bool found = wasmtime_component_type_import_nth(
201-
capi(), engine.capi(), nth, &name_data, &name_size, &item);
273+
bool found = wasmtime_component_type_import_nth(capi(), engine.capi(), nth,
274+
&name_data, &name_size, &e);
202275
if (!found) {
203276
return std::nullopt;
204277
}
205278
return std::make_pair(std::string_view(name_data, name_size),
206-
wasmtime::component::ComponentItem(std::move(item)));
279+
wasmtime::component::ComponentExtern(e));
207280
}
208281

209-
inline std::optional<wasmtime::component::ComponentItem>
282+
inline std::optional<wasmtime::component::ComponentExtern>
210283
wasmtime::component::ComponentType::export_get(const wasmtime::Engine &engine,
211284
std::string_view name) const {
212-
wasmtime_component_item_t item;
213-
bool found = wasmtime_component_type_export_get(
214-
capi(), engine.capi(), name.data(), name.size(), &item);
285+
wasmtime_component_extern_t *e;
286+
bool found = wasmtime_component_type_export_get(capi(), engine.capi(),
287+
name.data(), name.size(), &e);
215288
if (!found) {
216289
return std::nullopt;
217290
}
218-
return wasmtime::component::ComponentItem(std::move(item));
291+
return wasmtime::component::ComponentExtern(e);
219292
}
220293

221294
inline std::optional<
222-
std::pair<std::string_view, wasmtime::component::ComponentItem>>
295+
std::pair<std::string_view, wasmtime::component::ComponentExtern>>
223296
wasmtime::component::ComponentType::export_nth(const wasmtime::Engine &engine,
224297
size_t nth) const {
225-
wasmtime_component_item_t item;
298+
wasmtime_component_extern_t *e;
226299
const char *name_data;
227300
size_t name_size;
228-
bool found = wasmtime_component_type_export_nth(
229-
capi(), engine.capi(), nth, &name_data, &name_size, &item);
301+
bool found = wasmtime_component_type_export_nth(capi(), engine.capi(), nth,
302+
&name_data, &name_size, &e);
230303
if (!found) {
231304
return std::nullopt;
232305
}
233306
return std::make_pair(std::string_view(name_data, name_size),
234-
wasmtime::component::ComponentItem(std::move(item)));
307+
wasmtime::component::ComponentExtern(e));
235308
}
236309

237310
inline const wasmtime::component::ComponentInstanceType &

crates/c-api/include/wasmtime/component/types/instance.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
extern "C" {
1414
#endif
1515

16-
struct wasmtime_component_item_t;
16+
struct wasmtime_component_extern_t;
1717

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

4040
/// \brief Retrieves the export with the specified name.
4141
///
42-
/// The returned `wasmtime_component_item_t` must be deallocated with
43-
/// `wasmtime_component_item_delete`.
42+
/// The returned `wasmtime_component_extern_t` must be deallocated with
43+
/// `wasmtime_component_extern_delete`.
4444
WASM_API_EXTERN
4545
bool wasmtime_component_instance_type_export_get(
4646
const wasmtime_component_instance_type_t *ty, const wasm_engine_t *engine,
47-
const char *name, size_t name_len, struct wasmtime_component_item_t *ret);
47+
const char *name, size_t name_len,
48+
struct wasmtime_component_extern_t **ret);
4849

4950
/// \brief Retrieves the nth export.
5051
///
51-
/// The returned `wasmtime_component_item_t` must be deallocated with
52-
/// `wasmtime_component_item_delete`.
52+
/// The returned `wasmtime_component_extern_t` must be deallocated with
53+
/// `wasmtime_component_extern_delete`.
5354
WASM_API_EXTERN
5455
bool wasmtime_component_instance_type_export_nth(
5556
const wasmtime_component_instance_type_t *ty, const wasm_engine_t *engine,
5657
size_t nth, const char **name_ret, size_t *name_len_ret,
57-
struct wasmtime_component_item_t *type_ret);
58+
struct wasmtime_component_extern_t **ret);
5859

5960
#ifdef __cplusplus
6061
} // extern "C"

0 commit comments

Comments
 (0)