Skip to content
Draft
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ publish
vendor
examples/build
examples/.cache
crates/c-api/build
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it ok to do this? I kept getting things to commit locally, so I added this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this is fine to have here, no worries

*.coredump
*.smt2
cranelift/isle/veri/veri_engine/test_output
Expand Down
8 changes: 7 additions & 1 deletion crates/c-api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ else()
endif()
endif()

set(WASMTIME_TARGET_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../target/${WASMTIME_TARGET}/${WASMTIME_BUILD_TYPE})
# Respect CARGO_TARGET_DIR if set, allowing users to customize where Cargo
# outputs build artifacts
if(DEFINED ENV{CARGO_TARGET_DIR})
set(WASMTIME_TARGET_DIR $ENV{CARGO_TARGET_DIR}/${WASMTIME_TARGET}/${WASMTIME_BUILD_TYPE})
else()
set(WASMTIME_TARGET_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../target/${WASMTIME_TARGET}/${WASMTIME_BUILD_TYPE})
endif()

if(WASMTIME_TARGET MATCHES "apple")
set(WASMTIME_SHARED_FILES libwasmtime.dylib)
Expand Down
43 changes: 43 additions & 0 deletions crates/c-api/include/wasmtime/component/types/val.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,43 @@ WASM_API_EXTERN bool wasmtime_component_stream_type_ty(
const wasmtime_component_stream_type_t *ty,
struct wasmtime_component_valtype_t *type_ret);

// ----------- maps ------------------------------------------------------------

/// \brief Opaque type representing a component map type.
typedef struct wasmtime_component_map_type wasmtime_component_map_type_t;

/// \brief Clones a component map type.
///
/// The returned pointer must be deallocated with
/// `wasmtime_component_map_type_delete`.
WASM_API_EXTERN wasmtime_component_map_type_t *
wasmtime_component_map_type_clone(const wasmtime_component_map_type_t *ty);

/// \brief Compares two component map types for equality.
WASM_API_EXTERN bool
wasmtime_component_map_type_equal(const wasmtime_component_map_type_t *a,
const wasmtime_component_map_type_t *b);

/// \brief Deallocates a component map type.
WASM_API_EXTERN void
wasmtime_component_map_type_delete(wasmtime_component_map_type_t *ptr);

/// \brief Returns the key type of a component map type.
///
/// The returned type must be deallocated with
/// `wasmtime_component_valtype_delete`.
WASM_API_EXTERN void
wasmtime_component_map_type_key(const wasmtime_component_map_type_t *ty,
struct wasmtime_component_valtype_t *type_ret);

/// \brief Returns the value type of a component map type.
///
/// The returned type must be deallocated with
/// `wasmtime_component_valtype_delete`.
WASM_API_EXTERN void wasmtime_component_map_type_value(
const wasmtime_component_map_type_t *ty,
struct wasmtime_component_valtype_t *type_ret);

// ----------- valtype ---------------------------------------------------------

/// \brief Value of #wasmtime_component_valtype_kind_t meaning that
Expand Down Expand Up @@ -415,6 +452,9 @@ WASM_API_EXTERN bool wasmtime_component_stream_type_ty(
/// \brief Value of #wasmtime_component_valtype_kind_t meaning that
/// #wasmtime_component_valtype_t is an `error context` WIT type.
#define WASMTIME_COMPONENT_VALTYPE_ERROR_CONTEXT 25
/// \brief Value of #wasmtime_component_valtype_kind_t meaning that
/// #wasmtime_component_valtype_t is a `map` WIT type.
#define WASMTIME_COMPONENT_VALTYPE_MAP 26

/// \brief Discriminant used in #wasmtime_component_valtype_t::kind
typedef uint8_t wasmtime_component_valtype_kind_t;
Expand Down Expand Up @@ -457,6 +497,9 @@ typedef union wasmtime_component_valtype_union {
/// Field used if #wasmtime_component_valtype_t::kind is
/// #WASMTIME_COMPONENT_VALTYPE_STREAM
wasmtime_component_stream_type_t *stream;
/// Field used if #wasmtime_component_valtype_t::kind is
/// #WASMTIME_COMPONENT_VALTYPE_MAP
wasmtime_component_map_type_t *map;
} wasmtime_component_valtype_union_t;

/// \brief Represents a single value type in the component model.
Expand Down
40 changes: 40 additions & 0 deletions crates/c-api/include/wasmtime/component/types/val.hh
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,19 @@ class StreamType {
std::optional<ValType> ty() const;
};

/**
* \brief Represents a component map type.
*/
class MapType {
WASMTIME_CLONE_EQUAL_WRAPPER(MapType, wasmtime_component_map_type);

/// Returns the key type of this map type.
ValType key() const;

/// Returns the value type of this map type.
ValType value() const;
};

/**
* \brief Represents a component value type.
*/
Expand Down Expand Up @@ -382,6 +395,12 @@ public:
ty.of.stream = stream.capi_release();
}

/// Creates a map value type.
ValType(MapType map) {
ty.kind = WASMTIME_COMPONENT_VALTYPE_MAP;
ty.of.map = map.capi_release();
}

/// Returns the kind of this value type.
wasmtime_component_valtype_kind_t kind() const { return ty.kind; }

Expand Down Expand Up @@ -481,6 +500,9 @@ public:
return ty.kind == WASMTIME_COMPONENT_VALTYPE_ERROR_CONTEXT;
}

/// Returns true if this is a map type.
bool is_map() const { return ty.kind == WASMTIME_COMPONENT_VALTYPE_MAP; }

/// Returns the list type, asserting that this is indeed a list.
const ListType &list() const {
assert(is_list());
Expand Down Expand Up @@ -553,6 +575,12 @@ public:
return *StreamType::from_capi(&ty.of.stream);
}

/// Returns the map type, asserting that this is indeed a map.
const MapType &map() const {
assert(is_map());
return *MapType::from_capi(&ty.of.map);
}

/// \brief Returns the underlying C API pointer.
const wasmtime_component_valtype_t *capi() const { return &ty; }
/// \brief Returns the underlying C API pointer.
Expand Down Expand Up @@ -640,6 +668,18 @@ inline std::optional<ValType> StreamType::ty() const {
return std::nullopt;
}

inline ValType MapType::key() const {
wasmtime_component_valtype_t type_ret;
wasmtime_component_map_type_key(ptr.get(), &type_ret);
return ValType(std::move(type_ret));
}

inline ValType MapType::value() const {
wasmtime_component_valtype_t type_ret;
wasmtime_component_map_type_value(ptr.get(), &type_ret);
return ValType(std::move(type_ret));
}

} // namespace component
} // namespace wasmtime

Expand Down
16 changes: 16 additions & 0 deletions crates/c-api/include/wasmtime/component/val.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,13 @@ typedef uint8_t wasmtime_component_valkind_t;
/// \brief Value of #wasmtime_component_valkind_t meaning that
/// #wasmtime_component_val_t is a resource
#define WASMTIME_COMPONENT_RESOURCE 21
/// \brief Value of #wasmtime_component_valkind_t meaning that
/// #wasmtime_component_val_t is a map
#define WASMTIME_COMPONENT_MAP 22

struct wasmtime_component_val;
struct wasmtime_component_valrecord_entry;
struct wasmtime_component_valmap_entry;

#define DECLARE_VEC(name, type) \
/** \brief A vec of a type */ \
Expand Down Expand Up @@ -296,6 +300,7 @@ DECLARE_VEC(wasmtime_component_valrecord,
struct wasmtime_component_valrecord_entry)
DECLARE_VEC(wasmtime_component_valtuple, struct wasmtime_component_val)
DECLARE_VEC(wasmtime_component_valflags, wasm_name_t)
DECLARE_VEC(wasmtime_component_valmap, struct wasmtime_component_valmap_entry)

#undef DECLARE_VEC

Expand Down Expand Up @@ -366,6 +371,8 @@ typedef union {
wasmtime_component_valresult_t result;
/// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_FLAGS
wasmtime_component_valflags_t flags;
/// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_MAP
wasmtime_component_valmap_t map;
/// Field used if #wasmtime_component_val_t::kind is
/// #WASMTIME_COMPONENT_RESOURCE
wasmtime_component_resource_any_t *resource;
Expand All @@ -389,6 +396,15 @@ typedef struct wasmtime_component_valrecord_entry {
wasmtime_component_val_t val;
} wasmtime_component_valrecord_entry_t;

/// \brief A pair of a key and a value that represents one entry in a value
/// with kind #WASMTIME_COMPONENT_MAP
typedef struct wasmtime_component_valmap_entry {
/// The key of this entry
wasmtime_component_val_t key;
/// The value of this entry
wasmtime_component_val_t value;
} wasmtime_component_valmap_entry_t;

/// \brief Allocates a new `wasmtime_component_val_t` on the heap, initializing
/// it with the contents of `val`.
///
Expand Down
84 changes: 83 additions & 1 deletion crates/c-api/include/wasmtime/component/val.hh
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,63 @@ public:
}
};

/// \brief Class representing an entry in a map value.
class MapEntry {
friend class Map;

wasmtime_component_valmap_entry_t entry;

// This value can't be constructed or destructed, it's only used in iteration
// of `Map`.
MapEntry() = delete;
~MapEntry() = delete;

static const MapEntry *
from_capi(const wasmtime_component_valmap_entry_t *capi) {
return reinterpret_cast<const MapEntry *>(capi);
}

public:
/// \brief Returns the key of this map entry.
const Val &key() const { return *detail::val_from_capi(&entry.key); }

/// \brief Returns the value of this map entry.
const Val &value() const { return *detail::val_from_capi(&entry.value); }
};

/// \brief Class representing a component model map, a collection of key/value
/// pairs.
class Map {
friend class Val;

VAL_REPR(Map, wasmtime_component_valmap_t);

static void transfer(Raw &&from, Raw &to) {
to = from;
from.size = 0;
from.data = nullptr;
}

void copy(const Raw &other) { wasmtime_component_valmap_copy(&raw, &other); }

void destroy() { wasmtime_component_valmap_delete(&raw); }

public:
/// Creates a new map from the key/value pairs provided.
Map(std::vector<std::pair<Val, Val>> entries);

/// \brief Returns the number of entries in the map.
size_t size() const { return raw.size; }

/// \brief Returns an iterator to the beginning of the map entries.
const MapEntry *begin() const { return MapEntry::from_capi(raw.data); }

/// \brief Returns an iterator to the end of the map entries.
const MapEntry *end() const {
return MapEntry::from_capi(raw.data + raw.size);
}
};

class ResourceHost;

/// Class representing a component model `resource` value which is either a
Expand Down Expand Up @@ -644,6 +701,12 @@ public:
Flags::transfer(std::move(f.raw), raw.of.flags);
}

/// Creates a new map value.
Val(Map m) {
raw.kind = WASMTIME_COMPONENT_MAP;
Map::transfer(std::move(m.raw), raw.of.map);
}

/// Creates a new resource value.
Val(ResourceAny r) {
raw.kind = WASMTIME_COMPONENT_RESOURCE;
Expand Down Expand Up @@ -833,11 +896,20 @@ public:
/// \brief Returns whether this value is a resource.
bool is_resource() const { return raw.kind == WASMTIME_COMPONENT_RESOURCE; }

/// \brief Returns the flags value, only valid if `is_flags()`.
/// \brief Returns the resource value, only valid if `is_resource()`.
const ResourceAny &get_resource() const {
assert(is_resource());
return *ResourceAny::from_capi(&raw.of.resource);
}

/// \brief Returns whether this value is a map.
bool is_map() const { return raw.kind == WASMTIME_COMPONENT_MAP; }

/// \brief Returns the map value, only valid if `is_map()`.
const Map &get_map() const {
assert(is_map());
return *Map::from_capi(&raw.of.map);
}
};

#undef VAL_REPR
Expand All @@ -852,6 +924,16 @@ inline Record::Record(std::vector<std::pair<std::string_view, Val>> entries) {
}
}

inline Map::Map(std::vector<std::pair<Val, Val>> entries) {
wasmtime_component_valmap_new_uninit(&raw, entries.size());
auto dst = raw.data;
for (auto &&[key, val] : entries) {
new (&dst->key) Val(std::move(key));
new (&dst->value) Val(std::move(val));
dst++;
}
}

inline List::List(std::vector<Val> values) {
wasmtime_component_vallist_new_uninit(&raw, values.size());
auto dst = raw.data;
Expand Down
9 changes: 9 additions & 0 deletions crates/c-api/include/wasmtime/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,15 @@ WASM_API_EXTERN void wasmtime_pooling_allocation_strategy_set(
*/
WASMTIME_CONFIG_PROP(void, wasm_component_model, bool)

/**
* \brief Configures whether the WebAssembly component-model map type will be
* enabled for compilation.
*
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_component_model_map.
*/
WASMTIME_CONFIG_PROP(void, wasm_component_model_map, bool)

#endif // WASMTIME_FEATURE_COMPONENT_MODEL

#ifdef __cplusplus
Expand Down
8 changes: 8 additions & 0 deletions crates/c-api/include/wasmtime/config.hh
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,14 @@ class Config {
void wasm_component_model(bool enable) {
wasmtime_config_wasm_component_model_set(ptr.get(), enable);
}

/// \brief Configures whether the WebAssembly component model map type will be
/// enabled
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_component_model_map
void wasm_component_model_map(bool enable) {
wasmtime_config_wasm_component_model_map_set(ptr.get(), enable);
}
#endif // WASMTIME_FEATURE_COMPONENT_MODEL

#ifdef WASMTIME_FEATURE_PARALLEL_COMPILATION
Expand Down
8 changes: 8 additions & 0 deletions crates/c-api/src/component/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ pub extern "C" fn wasmtime_config_wasm_component_model_set(c: &mut wasm_config_t
c.config.wasm_component_model(enable);
}

#[unsafe(no_mangle)]
pub extern "C" fn wasmtime_config_wasm_component_model_map_set(
c: &mut wasm_config_t,
enable: bool,
) {
c.config.wasm_component_model_map(enable);
}

#[derive(Clone)]
#[repr(transparent)]
pub struct wasmtime_component_t {
Expand Down
Loading