Skip to content
Open
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
16 changes: 10 additions & 6 deletions crates/wasmparser/src/validator/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2118,9 +2118,11 @@ impl ComponentState {
}

self.cabi_memory_at(memory, offset)?;

self.core_funcs
.push(types.intern_func_type(FuncType::new([ValType::I32; 2], [ValType::I32]), offset));
let memory64 = self.memory_at(memory, offset)?.memory64;
let ty = if memory64 { ValType::I64 } else { ValType::I32 };
self.core_funcs.push(
types.intern_func_type(FuncType::new([ValType::I32, ty], [ValType::I32]), offset),
);
Ok(())
}

Expand All @@ -2138,9 +2140,11 @@ impl ComponentState {
}

self.cabi_memory_at(memory, offset)?;

self.core_funcs
.push(types.intern_func_type(FuncType::new([ValType::I32; 2], [ValType::I32]), offset));
let memory64 = self.memory_at(memory, offset)?.memory64;
let ty = if memory64 { ValType::I64 } else { ValType::I32 };
self.core_funcs.push(
types.intern_func_type(FuncType::new([ValType::I32, ty], [ValType::I32]), offset),
);
Ok(())
}

Expand Down
53 changes: 41 additions & 12 deletions crates/wit-component/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,16 +633,16 @@ impl ImportMap {
return Ok(Import::WaitableSetNew);
}

if let Some(info) = names.waitable_set_wait(name) {
let expected = FuncType::new([ValType::I32; 2], [ValType::I32]);
if let Some((info, result_ty)) = names.waitable_set_wait(name) {
let expected = FuncType::new([ValType::I32, result_ty], [ValType::I32]);
validate_func_sig(name, &expected, ty)?;
return Ok(Import::WaitableSetWait {
cancellable: info.cancellable,
});
}

if let Some(info) = names.waitable_set_poll(name) {
let expected = FuncType::new([ValType::I32; 2], [ValType::I32]);
if let Some((info, result_ty)) = names.waitable_set_poll(name) {
let expected = FuncType::new([ValType::I32, result_ty], [ValType::I32]);
validate_func_sig(name, &expected, ty)?;
return Ok(Import::WaitableSetPoll {
cancellable: info.cancellable,
Expand Down Expand Up @@ -1580,8 +1580,8 @@ trait NameMangling {
fn backpressure_inc(&self, name: &str) -> bool;
fn backpressure_dec(&self, name: &str) -> bool;
fn waitable_set_new(&self, name: &str) -> bool;
fn waitable_set_wait(&self, name: &str) -> Option<MaybeCancellable<()>>;
fn waitable_set_poll(&self, name: &str) -> Option<MaybeCancellable<()>>;
fn waitable_set_wait(&self, name: &str) -> Option<(MaybeCancellable<()>, ValType)>;
fn waitable_set_poll(&self, name: &str) -> Option<(MaybeCancellable<()>, ValType)>;
fn waitable_set_drop(&self, name: &str) -> bool;
fn waitable_join(&self, name: &str) -> bool;
fn thread_yield(&self, name: &str) -> Option<MaybeCancellable<()>>;
Expand Down Expand Up @@ -1747,10 +1747,10 @@ impl NameMangling for Standard {
fn waitable_set_new(&self, _name: &str) -> bool {
false
}
fn waitable_set_wait(&self, _name: &str) -> Option<MaybeCancellable<()>> {
fn waitable_set_wait(&self, _name: &str) -> Option<(MaybeCancellable<()>, ValType)> {
None
}
fn waitable_set_poll(&self, _name: &str) -> Option<MaybeCancellable<()>> {
fn waitable_set_poll(&self, _name: &str) -> Option<(MaybeCancellable<()>, ValType)> {
None
}
fn waitable_set_drop(&self, _name: &str) -> bool {
Expand Down Expand Up @@ -2142,6 +2142,23 @@ impl Legacy {
None
}
}

/// Matches a name with the given prefix and either no suffix (for backwards compat) or
/// "-i32" or "-i64".
/// Returns a `ValType` based on the suffix and defaults to `I32`.
fn match_with_optional_type_suffix(name: &str, match_prefix: &str) -> Option<ValType> {
let tail = name.strip_prefix(match_prefix)?.strip_suffix(']')?;
if tail.is_empty() {
Some(ValType::I32)
} else {
match tail.strip_prefix('-')? {
"i32" => Some(ValType::I32),
"i64" => Some(ValType::I64),
// Other suffixes
_ => None,
}
}
}
}

impl NameMangling for Legacy {
Expand Down Expand Up @@ -2196,11 +2213,23 @@ impl NameMangling for Legacy {
fn waitable_set_new(&self, name: &str) -> bool {
name == "[waitable-set-new]"
}
fn waitable_set_wait(&self, name: &str) -> Option<MaybeCancellable<()>> {
self.match_with_cancellable_prefix(name, "[waitable-set-wait]")
fn waitable_set_wait(&self, name: &str) -> Option<(MaybeCancellable<()>, ValType)> {
let (cancellable, clean_name) = self.strip_cancellable_prefix(name);
let mb_cancellable = MaybeCancellable {
inner: (),
cancellable,
};
let result_ty = Legacy::match_with_optional_type_suffix(clean_name, "[waitable-set-wait")?;
Some((mb_cancellable, result_ty))
}
fn waitable_set_poll(&self, name: &str) -> Option<MaybeCancellable<()>> {
self.match_with_cancellable_prefix(name, "[waitable-set-poll]")
fn waitable_set_poll(&self, name: &str) -> Option<(MaybeCancellable<()>, ValType)> {
let (cancellable, clean_name) = self.strip_cancellable_prefix(name);
let mb_cancellable = MaybeCancellable {
inner: (),
cancellable,
};
let result_ty = Legacy::match_with_optional_type_suffix(clean_name, "[waitable-set-poll")?;
Some((mb_cancellable, result_ty))
}
fn waitable_set_drop(&self, name: &str) -> bool {
name == "[waitable-set-drop]"
Expand Down
78 changes: 78 additions & 0 deletions tests/cli/component-model/memory64/waitable-set.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
;; RUN: wast --assert default --snapshot tests/snapshots % -f cm-async,cm64

;; waitable-set.wait

(component
(core module $libc (memory (export "memory") i64 1))
(core instance $libc (instantiate $libc))
(core module $m
(import "" "waitable-set.wait" (func $waitable-set-wait (param i32 i64) (result i32)))
)
(core func $waitable-set-wait (canon waitable-set.wait cancellable (memory $libc "memory")))
(core instance $i (instantiate $m (with "" (instance (export "waitable-set.wait" (func $waitable-set-wait))))))
)

(assert_invalid
(component
(core module $libc (memory (export "memory") 1))
(core instance $libc (instantiate $libc))
(core module $m
(import "" "waitable-set.wait" (func $waitable-set-wait (param i32 i64) (result i32)))
)
(core func $waitable-set-wait (canon waitable-set.wait cancellable (memory $libc "memory")))
(core instance $i (instantiate $m (with "" (instance (export "waitable-set.wait" (func $waitable-set-wait))))))
)
"type mismatch for export `waitable-set.wait`"
)

(assert_invalid
(component
(core module $libc (memory (export "memory") i64 1))
(core instance $libc (instantiate $libc))
(core module $m
(import "" "waitable-set.wait" (func $waitable-set-wait (param i32 i32) (result i32)))
)
(core func $waitable-set-wait (canon waitable-set.wait cancellable (memory $libc "memory")))
(core instance $i (instantiate $m (with "" (instance (export "waitable-set.wait" (func $waitable-set-wait))))))
)
"type mismatch for export `waitable-set.wait`"
)


;; waitable-set.poll

(component
(core module $libc (memory (export "memory") i64 1))
(core instance $libc (instantiate $libc))
(core module $m
(import "" "waitable-set.poll" (func $waitable-set-poll (param i32 i64) (result i32)))
)
(core func $waitable-set-poll (canon waitable-set.poll cancellable (memory $libc "memory")))
(core instance $i (instantiate $m (with "" (instance (export "waitable-set.poll" (func $waitable-set-poll))))))
)

(assert_invalid
(component
(core module $libc (memory (export "memory") 1))
(core instance $libc (instantiate $libc))
(core module $m
(import "" "waitable-set.poll" (func $waitable-set-poll (param i32 i64) (result i32)))
)
(core func $waitable-set-poll (canon waitable-set.poll cancellable (memory $libc "memory")))
(core instance $i (instantiate $m (with "" (instance (export "waitable-set.poll" (func $waitable-set-poll))))))
)
"type mismatch for export `waitable-set.poll`"
)

(assert_invalid
(component
(core module $libc (memory (export "memory") i64 1))
(core instance $libc (instantiate $libc))
(core module $m
(import "" "waitable-set.poll" (func $waitable-set-poll (param i32 i32) (result i32)))
)
(core func $waitable-set-poll (canon waitable-set.poll cancellable (memory $libc "memory")))
(core instance $i (instantiate $m (with "" (instance (export "waitable-set.poll" (func $waitable-set-poll))))))
)
"type mismatch for export `waitable-set.poll`"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"source_filename": "tests/cli/component-model/memory64/waitable-set.wast",
"commands": [
{
"type": "module",
"line": 5,
"filename": "waitable-set.0.wasm",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 16,
"filename": "waitable-set.1.wasm",
"module_type": "binary",
"text": "type mismatch for export `waitable-set.wait`"
},
{
"type": "assert_invalid",
"line": 29,
"filename": "waitable-set.2.wasm",
"module_type": "binary",
"text": "type mismatch for export `waitable-set.wait`"
},
{
"type": "module",
"line": 44,
"filename": "waitable-set.3.wasm",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 55,
"filename": "waitable-set.4.wasm",
"module_type": "binary",
"text": "type mismatch for export `waitable-set.poll`"
},
{
"type": "assert_invalid",
"line": 68,
"filename": "waitable-set.5.wasm",
"module_type": "binary",
"text": "type mismatch for export `waitable-set.poll`"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(component
(core module $libc (;0;)
(memory (;0;) i64 1)
(export "memory" (memory 0))
)
(core instance $libc (;0;) (instantiate $libc))
(core module $m (;1;)
(type (;0;) (func (param i32 i64) (result i32)))
(import "" "waitable-set.wait" (func $waitable-set-wait (;0;) (type 0)))
)
(alias core export $libc "memory" (core memory (;0;)))
(core func $waitable-set-wait (;0;) (canon waitable-set.wait cancellable (memory 0)))
(core instance (;1;)
(export "waitable-set.wait" (func $waitable-set-wait))
)
(core instance $i (;2;) (instantiate $m
(with "" (instance 1))
)
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(component
(core module $libc (;0;)
(memory (;0;) i64 1)
(export "memory" (memory 0))
)
(core instance $libc (;0;) (instantiate $libc))
(core module $m (;1;)
(type (;0;) (func (param i32 i64) (result i32)))
(import "" "waitable-set.poll" (func $waitable-set-poll (;0;) (type 0)))
)
(alias core export $libc "memory" (core memory (;0;)))
(core func $waitable-set-poll (;0;) (canon waitable-set.poll cancellable (memory 0)))
(core instance (;1;)
(export "waitable-set.poll" (func $waitable-set-poll))
)
(core instance $i (;2;) (instantiate $m
(with "" (instance 1))
)
)
)
Loading