Skip to content

Commit 6b6f675

Browse files
committed
Add support for map type
Signed-off-by: Yordis Prieto <[email protected]>
1 parent 967f460 commit 6b6f675

File tree

32 files changed

+2454
-912
lines changed

32 files changed

+2454
-912
lines changed

Cargo.lock

Lines changed: 1021 additions & 871 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -341,18 +341,20 @@ wit-bindgen = { version = "0.50.0", default-features = false }
341341
wit-bindgen-rust-macro = { version = "0.50.0", default-features = false }
342342

343343
# wasm-tools family:
344-
wasmparser = { version = "0.243.0", default-features = false, features = ['simd'] }
345-
wat = "1.243.0"
346-
wast = "243.0.0"
347-
wasmprinter = "0.243.0"
348-
wasm-encoder = "0.243.0"
349-
wasm-smith = "0.243.0"
350-
wasm-mutate = "0.243.0"
351-
wit-parser = "0.243.0"
352-
wit-component = "0.243.0"
353-
wasm-wave = "0.243.0"
354-
wasm-compose = "0.243.0"
355-
json-from-wast = "0.243.0"
344+
# TODO: well, these are not published to crates.io yet, so we need to use the git repository.
345+
# I am gonna remove this once the feature is "completed" and the crates are published to crates.io.
346+
wasmparser = { git = "https://github.com/bytecodealliance/wasm-tools", default-features = false, features = ['simd'] }
347+
wat = { git = "https://github.com/bytecodealliance/wasm-tools" }
348+
wast = { git = "https://github.com/bytecodealliance/wasm-tools" }
349+
wasmprinter = { git = "https://github.com/bytecodealliance/wasm-tools" }
350+
wasm-encoder = { git = "https://github.com/bytecodealliance/wasm-tools" }
351+
wasm-smith = { git = "https://github.com/bytecodealliance/wasm-tools" }
352+
wasm-mutate = { git = "https://github.com/bytecodealliance/wasm-tools" }
353+
wit-parser = { git = "https://github.com/bytecodealliance/wasm-tools" }
354+
wit-component = { git = "https://github.com/bytecodealliance/wasm-tools" }
355+
wasm-wave = { git = "https://github.com/bytecodealliance/wasm-tools" }
356+
wasm-compose = { git = "https://github.com/bytecodealliance/wasm-tools" }
357+
json-from-wast = { git = "https://github.com/bytecodealliance/wasm-tools" }
356358

357359
# Non-Bytecode Alliance maintained dependencies:
358360
# --------------------------

crates/c-api/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ else()
3232
endif()
3333
endif()
3434

35-
set(WASMTIME_TARGET_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../target/${WASMTIME_TARGET}/${WASMTIME_BUILD_TYPE})
35+
# Respect CARGO_TARGET_DIR if set, allowing users to customize where Cargo
36+
# outputs build artifacts
37+
if(DEFINED ENV{CARGO_TARGET_DIR})
38+
set(WASMTIME_TARGET_DIR $ENV{CARGO_TARGET_DIR}/${WASMTIME_TARGET}/${WASMTIME_BUILD_TYPE})
39+
else()
40+
set(WASMTIME_TARGET_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../target/${WASMTIME_TARGET}/${WASMTIME_BUILD_TYPE})
41+
endif()
3642

3743
if(WASMTIME_TARGET MATCHES "apple")
3844
set(WASMTIME_SHARED_FILES libwasmtime.dylib)

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,43 @@ WASM_API_EXTERN bool wasmtime_component_stream_type_ty(
335335
const wasmtime_component_stream_type_t *ty,
336336
struct wasmtime_component_valtype_t *type_ret);
337337

338+
// ----------- maps ------------------------------------------------------------
339+
340+
/// \brief Opaque type representing a component map type.
341+
typedef struct wasmtime_component_map_type wasmtime_component_map_type_t;
342+
343+
/// \brief Clones a component map type.
344+
///
345+
/// The returned pointer must be deallocated with
346+
/// `wasmtime_component_map_type_delete`.
347+
WASM_API_EXTERN wasmtime_component_map_type_t *
348+
wasmtime_component_map_type_clone(const wasmtime_component_map_type_t *ty);
349+
350+
/// \brief Compares two component map types for equality.
351+
WASM_API_EXTERN bool
352+
wasmtime_component_map_type_equal(const wasmtime_component_map_type_t *a,
353+
const wasmtime_component_map_type_t *b);
354+
355+
/// \brief Deallocates a component map type.
356+
WASM_API_EXTERN void
357+
wasmtime_component_map_type_delete(wasmtime_component_map_type_t *ptr);
358+
359+
/// \brief Returns the key type of a component map type.
360+
///
361+
/// The returned type must be deallocated with
362+
/// `wasmtime_component_valtype_delete`.
363+
WASM_API_EXTERN void wasmtime_component_map_type_key(
364+
const wasmtime_component_map_type_t *ty,
365+
struct wasmtime_component_valtype_t *type_ret);
366+
367+
/// \brief Returns the value type of a component map type.
368+
///
369+
/// The returned type must be deallocated with
370+
/// `wasmtime_component_valtype_delete`.
371+
WASM_API_EXTERN void wasmtime_component_map_type_value(
372+
const wasmtime_component_map_type_t *ty,
373+
struct wasmtime_component_valtype_t *type_ret);
374+
338375
// ----------- valtype ---------------------------------------------------------
339376

340377
/// \brief Value of #wasmtime_component_valtype_kind_t meaning that
@@ -415,6 +452,9 @@ WASM_API_EXTERN bool wasmtime_component_stream_type_ty(
415452
/// \brief Value of #wasmtime_component_valtype_kind_t meaning that
416453
/// #wasmtime_component_valtype_t is an `error context` WIT type.
417454
#define WASMTIME_COMPONENT_VALTYPE_ERROR_CONTEXT 25
455+
/// \brief Value of #wasmtime_component_valtype_kind_t meaning that
456+
/// #wasmtime_component_valtype_t is a `map` WIT type.
457+
#define WASMTIME_COMPONENT_VALTYPE_MAP 26
418458

419459
/// \brief Discriminant used in #wasmtime_component_valtype_t::kind
420460
typedef uint8_t wasmtime_component_valtype_kind_t;
@@ -457,6 +497,9 @@ typedef union wasmtime_component_valtype_union {
457497
/// Field used if #wasmtime_component_valtype_t::kind is
458498
/// #WASMTIME_COMPONENT_VALTYPE_STREAM
459499
wasmtime_component_stream_type_t *stream;
500+
/// Field used if #wasmtime_component_valtype_t::kind is
501+
/// #WASMTIME_COMPONENT_VALTYPE_MAP
502+
wasmtime_component_map_type_t *map;
460503
} wasmtime_component_valtype_union_t;
461504

462505
/// \brief Represents a single value type in the component model.

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,19 @@ class StreamType {
178178
std::optional<ValType> ty() const;
179179
};
180180

181+
/**
182+
* \brief Represents a component map type.
183+
*/
184+
class MapType {
185+
WASMTIME_CLONE_EQUAL_WRAPPER(MapType, wasmtime_component_map_type);
186+
187+
/// Returns the key type of this map type.
188+
ValType key() const;
189+
190+
/// Returns the value type of this map type.
191+
ValType value() const;
192+
};
193+
181194
/**
182195
* \brief Represents a component value type.
183196
*/
@@ -382,6 +395,12 @@ public:
382395
ty.of.stream = stream.capi_release();
383396
}
384397

398+
/// Creates a map value type.
399+
ValType(MapType map) {
400+
ty.kind = WASMTIME_COMPONENT_VALTYPE_MAP;
401+
ty.of.map = map.capi_release();
402+
}
403+
385404
/// Returns the kind of this value type.
386405
wasmtime_component_valtype_kind_t kind() const { return ty.kind; }
387406

@@ -481,6 +500,9 @@ public:
481500
return ty.kind == WASMTIME_COMPONENT_VALTYPE_ERROR_CONTEXT;
482501
}
483502

503+
/// Returns true if this is a map type.
504+
bool is_map() const { return ty.kind == WASMTIME_COMPONENT_VALTYPE_MAP; }
505+
484506
/// Returns the list type, asserting that this is indeed a list.
485507
const ListType &list() const {
486508
assert(is_list());
@@ -553,6 +575,12 @@ public:
553575
return *StreamType::from_capi(&ty.of.stream);
554576
}
555577

578+
/// Returns the map type, asserting that this is indeed a map.
579+
const MapType &map() const {
580+
assert(is_map());
581+
return *MapType::from_capi(&ty.of.map);
582+
}
583+
556584
/// \brief Returns the underlying C API pointer.
557585
const wasmtime_component_valtype_t *capi() const { return &ty; }
558586
/// \brief Returns the underlying C API pointer.
@@ -640,6 +668,18 @@ inline std::optional<ValType> StreamType::ty() const {
640668
return std::nullopt;
641669
}
642670

671+
inline ValType MapType::key() const {
672+
wasmtime_component_valtype_t type_ret;
673+
wasmtime_component_map_type_key(ptr.get(), &type_ret);
674+
return ValType(std::move(type_ret));
675+
}
676+
677+
inline ValType MapType::value() const {
678+
wasmtime_component_valtype_t type_ret;
679+
wasmtime_component_map_type_value(ptr.get(), &type_ret);
680+
return ValType(std::move(type_ret));
681+
}
682+
643683
} // namespace component
644684
} // namespace wasmtime
645685

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,13 @@ typedef uint8_t wasmtime_component_valkind_t;
266266
/// \brief Value of #wasmtime_component_valkind_t meaning that
267267
/// #wasmtime_component_val_t is a resource
268268
#define WASMTIME_COMPONENT_RESOURCE 21
269+
/// \brief Value of #wasmtime_component_valkind_t meaning that
270+
/// #wasmtime_component_val_t is a map
271+
#define WASMTIME_COMPONENT_MAP 22
269272

270273
struct wasmtime_component_val;
271274
struct wasmtime_component_valrecord_entry;
275+
struct wasmtime_component_valmap_entry;
272276

273277
#define DECLARE_VEC(name, type) \
274278
/** \brief A vec of a type */ \
@@ -296,6 +300,8 @@ DECLARE_VEC(wasmtime_component_valrecord,
296300
struct wasmtime_component_valrecord_entry)
297301
DECLARE_VEC(wasmtime_component_valtuple, struct wasmtime_component_val)
298302
DECLARE_VEC(wasmtime_component_valflags, wasm_name_t)
303+
DECLARE_VEC(wasmtime_component_valmap,
304+
struct wasmtime_component_valmap_entry)
299305

300306
#undef DECLARE_VEC
301307

@@ -366,6 +372,8 @@ typedef union {
366372
wasmtime_component_valresult_t result;
367373
/// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_FLAGS
368374
wasmtime_component_valflags_t flags;
375+
/// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_MAP
376+
wasmtime_component_valmap_t map;
369377
/// Field used if #wasmtime_component_val_t::kind is
370378
/// #WASMTIME_COMPONENT_RESOURCE
371379
wasmtime_component_resource_any_t *resource;
@@ -389,6 +397,15 @@ typedef struct wasmtime_component_valrecord_entry {
389397
wasmtime_component_val_t val;
390398
} wasmtime_component_valrecord_entry_t;
391399

400+
/// \brief A pair of a key and a value that represents one entry in a value
401+
/// with kind #WASMTIME_COMPONENT_MAP
402+
typedef struct wasmtime_component_valmap_entry {
403+
/// The key of this entry
404+
wasmtime_component_val_t key;
405+
/// The value of this entry
406+
wasmtime_component_val_t value;
407+
} wasmtime_component_valmap_entry_t;
408+
392409
/// \brief Allocates a new `wasmtime_component_val_t` on the heap, initializing
393410
/// it with the contents of `val`.
394411
///

crates/c-api/src/component/types/val.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub enum wasmtime_component_valtype_t {
3131
Future(Box<wasmtime_component_future_type_t>),
3232
Stream(Box<wasmtime_component_stream_type_t>),
3333
ErrorContext,
34+
Map(Box<wasmtime_component_map_type_t>),
3435
}
3536

3637
impl From<Type> for wasmtime_component_valtype_t {
@@ -61,6 +62,7 @@ impl From<Type> for wasmtime_component_valtype_t {
6162
Type::Borrow(ty) => Self::Borrow(Box::new(ty.into())),
6263
Type::Future(ty) => Self::Future(Box::new(ty.into())),
6364
Type::Stream(ty) => Self::Stream(Box::new(ty.into())),
65+
Type::Map(ty) => Self::Map(Box::new(ty.into())),
6466
Type::ErrorContext => Self::ErrorContext,
6567
}
6668
}
@@ -108,6 +110,33 @@ pub extern "C" fn wasmtime_component_list_type_element(
108110
type_ret.write(ty.ty.ty().into());
109111
}
110112

113+
type_wrapper! {
114+
#[derive(PartialEq)]
115+
pub struct wasmtime_component_map_type_t {
116+
pub(crate) ty: Map,
117+
}
118+
119+
clone: wasmtime_component_map_type_clone,
120+
delete: wasmtime_component_map_type_delete,
121+
equal: wasmtime_component_map_type_equal,
122+
}
123+
124+
#[unsafe(no_mangle)]
125+
pub extern "C" fn wasmtime_component_map_type_key(
126+
ty: &wasmtime_component_map_type_t,
127+
type_ret: &mut MaybeUninit<wasmtime_component_valtype_t>,
128+
) {
129+
type_ret.write(ty.ty.key().into());
130+
}
131+
132+
#[unsafe(no_mangle)]
133+
pub extern "C" fn wasmtime_component_map_type_value(
134+
ty: &wasmtime_component_map_type_t,
135+
type_ret: &mut MaybeUninit<wasmtime_component_valtype_t>,
136+
) {
137+
type_ret.write(ty.ty.value().into());
138+
}
139+
111140
type_wrapper! {
112141
#[derive(PartialEq)]
113142
pub struct wasmtime_component_record_type_t {

crates/c-api/src/component/val.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ crate::declare_vecs! {
4545
copy: wasmtime_component_valflags_copy,
4646
delete: wasmtime_component_valflags_delete,
4747
)
48+
(
49+
name: wasmtime_component_valmap_t,
50+
ty: wasmtime_component_valmap_entry_t,
51+
new: wasmtime_component_valmap_new,
52+
empty: wasmtime_component_valmap_new_empty,
53+
uninit: wasmtime_component_valmap_new_uninit,
54+
copy: wasmtime_component_valmap_copy,
55+
delete: wasmtime_component_valmap_delete,
56+
)
4857
}
4958

5059
impl From<&wasmtime_component_vallist_t> for Vec<Val> {
@@ -63,13 +72,43 @@ impl From<&[Val]> for wasmtime_component_vallist_t {
6372
}
6473
}
6574

75+
impl From<&wasmtime_component_valmap_t> for Vec<(Val, Val)> {
76+
fn from(value: &wasmtime_component_valmap_t) -> Self {
77+
value
78+
.as_slice()
79+
.iter()
80+
.map(|entry| (Val::from(&entry.key), Val::from(&entry.value)))
81+
.collect()
82+
}
83+
}
84+
85+
impl From<&[(Val, Val)]> for wasmtime_component_valmap_t {
86+
fn from(value: &[(Val, Val)]) -> Self {
87+
value
88+
.iter()
89+
.map(|(k, v)| wasmtime_component_valmap_entry_t {
90+
key: wasmtime_component_val_t::from(k),
91+
value: wasmtime_component_val_t::from(v),
92+
})
93+
.collect::<Vec<_>>()
94+
.into()
95+
}
96+
}
97+
6698
#[derive(Clone)]
6799
#[repr(C)]
68100
pub struct wasmtime_component_valrecord_entry_t {
69101
name: wasm_name_t,
70102
val: wasmtime_component_val_t,
71103
}
72104

105+
#[derive(Clone, Default)]
106+
#[repr(C)]
107+
pub struct wasmtime_component_valmap_entry_t {
108+
key: wasmtime_component_val_t,
109+
value: wasmtime_component_val_t,
110+
}
111+
73112
impl Default for wasmtime_component_valrecord_entry_t {
74113
fn default() -> Self {
75114
Self {
@@ -233,6 +272,7 @@ pub enum wasmtime_component_val_t {
233272
Option(Option<Box<Self>>),
234273
Result(wasmtime_component_valresult_t),
235274
Flags(wasmtime_component_valflags_t),
275+
Map(wasmtime_component_valmap_t),
236276
Resource(Box<wasmtime_component_resource_any_t>),
237277
}
238278

@@ -275,6 +315,7 @@ impl From<&wasmtime_component_val_t> for Val {
275315
}
276316
wasmtime_component_val_t::Result(x) => Val::Result(x.into()),
277317
wasmtime_component_val_t::Flags(x) => Val::Flags(x.into()),
318+
wasmtime_component_val_t::Map(x) => Val::Map(x.into()),
278319
wasmtime_component_val_t::Resource(x) => Val::Resource(x.resource),
279320
}
280321
}
@@ -309,6 +350,7 @@ impl From<&Val> for wasmtime_component_val_t {
309350
),
310351
Val::Result(x) => wasmtime_component_val_t::Result(x.into()),
311352
Val::Flags(x) => wasmtime_component_val_t::Flags(x.as_slice().into()),
353+
Val::Map(x) => wasmtime_component_val_t::Map(x.as_slice().into()),
312354
Val::Resource(resource_any) => {
313355
wasmtime_component_val_t::Resource(Box::new(wasmtime_component_resource_any_t {
314356
resource: *resource_any,

crates/c-api/tests/component/types.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ TEST(types, valtype_list) {
187187
EXPECT_TRUE(elem.is_u8());
188188
}
189189

190+
TEST(types, valtype_map) {
191+
auto ty =
192+
result("(component (import \"f\" (func (result (map u32 string)))))");
193+
EXPECT_TRUE(ty.is_map());
194+
auto map_ty = ty.map();
195+
EXPECT_TRUE(map_ty.key().is_u32());
196+
EXPECT_TRUE(map_ty.value().is_string());
197+
}
198+
190199
TEST(types, valtype_record) {
191200
auto ty = result(R"(
192201
(component

crates/environ/src/compile/module_environ.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,7 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> {
331331
Payload::ImportSection(imports) => {
332332
self.validator.import_section(&imports)?;
333333

334-
let cnt = usize::try_from(imports.count()).unwrap();
335-
self.result.module.initializers.reserve(cnt);
336-
337-
for entry in imports {
334+
for entry in imports.into_imports() {
338335
let import = entry?;
339336
let ty = match import.ty {
340337
TypeRef::Func(index) => {

0 commit comments

Comments
 (0)