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
4 changes: 4 additions & 0 deletions ci/generate-spec-tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ fn copy_test(src: &Path, dst: &Path, features: fn(&Path) -> &str) {
// Temporary exception until WebAssembly/component-model#704 lands
Some("kebab.wast") => "FAIL",

// Temporary until WebAssembly/component-model#716 lands
Some("cancellable.wast") => "FAIL",
Some("binary.wast") if dst.ends_with("components/binary/binary.wast") => "FAIL",

Some(_) | None => "RUN",
};

Expand Down
38 changes: 16 additions & 22 deletions crates/wasm-encoder/src/component/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,16 +664,14 @@ impl ComponentBuilder {
}

/// Declares a new `waitable-set.wait` intrinsic.
pub fn waitable_set_wait(&mut self, cancellable: bool, memory: u32) -> u32 {
self.canonical_functions()
.waitable_set_wait(cancellable, memory);
pub fn waitable_set_wait(&mut self, memory: u32) -> u32 {
self.canonical_functions().waitable_set_wait(memory);
self.core_funcs.add(Some("waitable-set.wait"))
}

/// Declares a new `waitable-set.poll` intrinsic.
pub fn waitable_set_poll(&mut self, cancellable: bool, memory: u32) -> u32 {
self.canonical_functions()
.waitable_set_poll(cancellable, memory);
pub fn waitable_set_poll(&mut self, memory: u32) -> u32 {
self.canonical_functions().waitable_set_poll(memory);
self.core_funcs.add(Some("waitable-set.poll"))
}

Expand Down Expand Up @@ -709,42 +707,38 @@ impl ComponentBuilder {
}

/// Declares a new `thread.suspend` intrinsic.
pub fn thread_suspend(&mut self, cancellable: bool) -> u32 {
self.canonical_functions().thread_suspend(cancellable);
pub fn thread_suspend(&mut self) -> u32 {
self.canonical_functions().thread_suspend();
self.core_funcs.add(Some("thread.suspend"))
}

/// Declares a new `thread.yield` intrinsic.
pub fn thread_yield(&mut self, cancellable: bool) -> u32 {
self.canonical_functions().thread_yield(cancellable);
pub fn thread_yield(&mut self) -> u32 {
self.canonical_functions().thread_yield();
self.core_funcs.add(Some("thread.yield"))
}

/// Declares a new `thread.suspend-then-resume` intrinsic.
pub fn thread_suspend_then_resume(&mut self, cancellable: bool) -> u32 {
self.canonical_functions()
.thread_suspend_then_resume(cancellable);
pub fn thread_suspend_then_resume(&mut self) -> u32 {
self.canonical_functions().thread_suspend_then_resume();
self.core_funcs.add(Some("thread.suspend-then-resume"))
}

/// Declares a new `thread.yield-then-resume` intrinsic.
pub fn thread_yield_then_resume(&mut self, cancellable: bool) -> u32 {
self.canonical_functions()
.thread_yield_then_resume(cancellable);
pub fn thread_yield_then_resume(&mut self) -> u32 {
self.canonical_functions().thread_yield_then_resume();
self.core_funcs.add(Some("thread.yield-then-resume"))
}

/// Declares a new `thread.suspend-then-promote` intrinsic.
pub fn thread_suspend_then_promote(&mut self, cancellable: bool) -> u32 {
self.canonical_functions()
.thread_suspend_then_promote(cancellable);
pub fn thread_suspend_then_promote(&mut self) -> u32 {
self.canonical_functions().thread_suspend_then_promote();
self.core_funcs.add(Some("thread.suspend-then-promote"))
}

/// Declares a new `thread.yield-then-promote` intrinsic.
pub fn thread_yield_then_promote(&mut self, cancellable: bool) -> u32 {
self.canonical_functions()
.thread_yield_then_promote(cancellable);
pub fn thread_yield_then_promote(&mut self) -> u32 {
self.canonical_functions().thread_yield_then_promote();
self.core_funcs.add(Some("thread.yield-then-resume"))
}

Expand Down
32 changes: 16 additions & 16 deletions crates/wasm-encoder/src/component/canonicals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,19 +455,19 @@ impl CanonicalFunctionSection {

/// Declare a new `waitable-set.wait` intrinsic, used to block on a
/// `waitable-set`.
pub fn waitable_set_wait(&mut self, async_: bool, memory: u32) -> &mut Self {
pub fn waitable_set_wait(&mut self, memory: u32) -> &mut Self {
self.bytes.push(0x20);
self.bytes.push(if async_ { 1 } else { 0 });
self.bytes.push(0);
memory.encode(&mut self.bytes);
self.num_added += 1;
self
}

/// Declare a new `waitable-set.wait` intrinsic, used to check, without
/// blocking, if anything in a `waitable-set` is ready.
pub fn waitable_set_poll(&mut self, async_: bool, memory: u32) -> &mut Self {
pub fn waitable_set_poll(&mut self, memory: u32) -> &mut Self {
self.bytes.push(0x21);
self.bytes.push(if async_ { 1 } else { 0 });
self.bytes.push(0);
memory.encode(&mut self.bytes);
self.num_added += 1;
self
Expand Down Expand Up @@ -515,49 +515,49 @@ impl CanonicalFunctionSection {
}

/// Declare a new `thread.suspend` intrinsic.
pub fn thread_suspend(&mut self, cancellable: bool) -> &mut Self {
pub fn thread_suspend(&mut self) -> &mut Self {
self.bytes.push(0x29);
self.bytes.push(if cancellable { 1 } else { 0 });
self.bytes.push(0);
self.num_added += 1;
self
}

/// Declare a new `thread.yield` intrinsic.
pub fn thread_yield(&mut self, cancellable: bool) -> &mut Self {
pub fn thread_yield(&mut self) -> &mut Self {
self.bytes.push(0x0c);
self.bytes.push(if cancellable { 1 } else { 0 });
self.bytes.push(0);
self.num_added += 1;
self
}

/// Declare a new `thread.suspend-then-resume` intrinsic.
pub fn thread_suspend_then_resume(&mut self, cancellable: bool) -> &mut Self {
pub fn thread_suspend_then_resume(&mut self) -> &mut Self {
self.bytes.push(0x2a);
self.bytes.push(if cancellable { 1 } else { 0 });
self.bytes.push(0);
self.num_added += 1;
self
}

/// Declare a new `thread.yield-then-resume` intrinsic.
pub fn thread_yield_then_resume(&mut self, cancellable: bool) -> &mut Self {
pub fn thread_yield_then_resume(&mut self) -> &mut Self {
self.bytes.push(0x2b);
self.bytes.push(if cancellable { 1 } else { 0 });
self.bytes.push(0);
self.num_added += 1;
self
}

/// Declare a new `thread.suspend-then-promote` intrinsic.
pub fn thread_suspend_then_promote(&mut self, cancellable: bool) -> &mut Self {
pub fn thread_suspend_then_promote(&mut self) -> &mut Self {
self.bytes.push(0x2c);
self.bytes.push(if cancellable { 1 } else { 0 });
self.bytes.push(0);
self.num_added += 1;
self
}

/// Declare a new `thread.yield-then-promote` intrinsic.
pub fn thread_yield_then_promote(&mut self, cancellable: bool) -> &mut Self {
pub fn thread_yield_then_promote(&mut self) -> &mut Self {
self.bytes.push(0x2d);
self.bytes.push(if cancellable { 1 } else { 0 });
self.bytes.push(0);
self.num_added += 1;
self
}
Expand Down
38 changes: 16 additions & 22 deletions crates/wasm-encoder/src/reencode/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1091,17 +1091,11 @@ pub mod component_utils {
wasmparser::CanonicalFunction::WaitableSetNew => {
section.waitable_set_new();
}
wasmparser::CanonicalFunction::WaitableSetWait {
cancellable,
memory,
} => {
section.waitable_set_wait(cancellable, reencoder.memory_index(memory)?);
wasmparser::CanonicalFunction::WaitableSetWait { memory } => {
section.waitable_set_wait(reencoder.memory_index(memory)?);
}
wasmparser::CanonicalFunction::WaitableSetPoll {
cancellable,
memory,
} => {
section.waitable_set_poll(cancellable, reencoder.memory_index(memory)?);
wasmparser::CanonicalFunction::WaitableSetPoll { memory } => {
section.waitable_set_poll(reencoder.memory_index(memory)?);
}
wasmparser::CanonicalFunction::WaitableSetDrop => {
section.waitable_set_drop();
Expand All @@ -1123,23 +1117,23 @@ pub mod component_utils {
wasmparser::CanonicalFunction::ThreadResumeLater => {
section.thread_resume_later();
}
wasmparser::CanonicalFunction::ThreadSuspend { cancellable } => {
section.thread_suspend(cancellable);
wasmparser::CanonicalFunction::ThreadSuspend => {
section.thread_suspend();
}
wasmparser::CanonicalFunction::ThreadYield { cancellable } => {
section.thread_yield(cancellable);
wasmparser::CanonicalFunction::ThreadYield => {
section.thread_yield();
}
wasmparser::CanonicalFunction::ThreadSuspendThenResume { cancellable } => {
section.thread_suspend_then_resume(cancellable);
wasmparser::CanonicalFunction::ThreadSuspendThenResume => {
section.thread_suspend_then_resume();
}
wasmparser::CanonicalFunction::ThreadYieldThenResume { cancellable } => {
section.thread_yield_then_resume(cancellable);
wasmparser::CanonicalFunction::ThreadYieldThenResume => {
section.thread_yield_then_resume();
}
wasmparser::CanonicalFunction::ThreadSuspendThenPromote { cancellable } => {
section.thread_suspend_then_promote(cancellable);
wasmparser::CanonicalFunction::ThreadSuspendThenPromote => {
section.thread_suspend_then_promote();
}
wasmparser::CanonicalFunction::ThreadYieldThenPromote { cancellable } => {
section.thread_yield_then_promote(cancellable);
wasmparser::CanonicalFunction::ThreadYieldThenPromote => {
section.thread_yield_then_promote();
}
}
Ok(())
Expand Down
112 changes: 56 additions & 56 deletions crates/wasmparser/src/readers/component/canonicals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,7 @@ pub enum CanonicalFunction {
},
/// A function which yields control to the host so that other tasks are able
/// to make progress, if any.
ThreadYield {
/// If `true`, indicates the caller instance maybe reentered.
cancellable: bool,
},
ThreadYield,
/// A function to drop a specified task which has completed.
SubtaskDrop,
/// A function to cancel an in-progress task.
Expand Down Expand Up @@ -257,17 +254,11 @@ pub enum CanonicalFunction {
WaitableSetNew,
/// A function to block on the next item within a `waitable-set`.
WaitableSetWait {
/// Whether or not the guest can be reentered while calling this
/// function.
cancellable: bool,
/// Which memory the results of this operation are stored in.
memory: u32,
},
/// A function to check if any items are ready within a `waitable-set`.
WaitableSetPoll {
/// Whether or not the guest can be reentered while calling this
/// function.
cancellable: bool,
/// Which memory the results of this operation are stored in.
memory: u32,
},
Expand All @@ -287,30 +278,15 @@ pub enum CanonicalFunction {
/// A function to schedule the given thread to be resumed later.
ThreadResumeLater,
/// A function to suspend the current thread, immediately yielding to any transitive async-lowered calling component.
ThreadSuspend {
/// Whether or not the thread can be cancelled while suspended.
cancellable: bool,
},
ThreadSuspend,
/// The `thread.suspend-then-resume` intrinsic
ThreadSuspendThenResume {
/// Whether or not the thread can be cancelled while awaiting resumption.
cancellable: bool,
},
ThreadSuspendThenResume,
/// The `thread.yield-then-resume` intrinsic
ThreadYieldThenResume {
/// Whether or not the thread can be cancelled while yielding.
cancellable: bool,
},
ThreadYieldThenResume,
/// The `thread.suspend-then-promote` intrinsic
ThreadSuspendThenPromote {
/// Whether or not the thread can be cancelled while suspended.
cancellable: bool,
},
ThreadSuspendThenPromote,
/// The `thread.yield-then-promote` intrinsic
ThreadYieldThenPromote {
/// Whether or not the thread can be cancelled while yielding.
cancellable: bool,
},
ThreadYieldThenPromote,
}

/// A reader for the canonical section of a WebAssembly component.
Expand Down Expand Up @@ -409,14 +385,18 @@ impl<'a> FromReader<'a> for CanonicalFunction {
0x1e => CanonicalFunction::ErrorContextDrop,

0x1f => CanonicalFunction::WaitableSetNew,
0x20 => CanonicalFunction::WaitableSetWait {
cancellable: reader.read()?,
memory: reader.read()?,
},
0x21 => CanonicalFunction::WaitableSetPoll {
cancellable: reader.read()?,
memory: reader.read()?,
},
0x20 => {
read_legacy_cancellation_byte(reader)?;
CanonicalFunction::WaitableSetWait {
memory: reader.read()?,
}
}
0x21 => {
read_legacy_cancellation_byte(reader)?;
CanonicalFunction::WaitableSetPoll {
memory: reader.read()?,
}
}
0x22 => CanonicalFunction::WaitableSetDrop,
0x23 => CanonicalFunction::WaitableJoin,
0x26 => CanonicalFunction::ThreadIndex,
Expand All @@ -425,24 +405,30 @@ impl<'a> FromReader<'a> for CanonicalFunction {
table_index: reader.read()?,
},
0x28 => CanonicalFunction::ThreadResumeLater,
0x29 => CanonicalFunction::ThreadSuspend {
cancellable: reader.read()?,
},
0x0c => CanonicalFunction::ThreadYield {
cancellable: reader.read()?,
},
0x2a => CanonicalFunction::ThreadSuspendThenResume {
cancellable: reader.read()?,
},
0x2b => CanonicalFunction::ThreadYieldThenResume {
cancellable: reader.read()?,
},
0x2c => CanonicalFunction::ThreadSuspendThenPromote {
cancellable: reader.read()?,
},
0x2d => CanonicalFunction::ThreadYieldThenPromote {
cancellable: reader.read()?,
},
0x29 => {
read_legacy_cancellation_byte(reader)?;
CanonicalFunction::ThreadSuspend
}
0x0c => {
read_legacy_cancellation_byte(reader)?;
CanonicalFunction::ThreadYield
}
0x2a => {
read_legacy_cancellation_byte(reader)?;
CanonicalFunction::ThreadSuspendThenResume
}
0x2b => {
read_legacy_cancellation_byte(reader)?;
CanonicalFunction::ThreadYieldThenResume
}
0x2c => {
read_legacy_cancellation_byte(reader)?;
CanonicalFunction::ThreadSuspendThenPromote
}
0x2d => {
read_legacy_cancellation_byte(reader)?;
CanonicalFunction::ThreadYieldThenPromote
}
0x40 => CanonicalFunction::ThreadSpawnRef {
func_ty_index: reader.read()?,
},
Expand All @@ -462,6 +448,20 @@ fn read_opts(reader: &mut BinaryReader<'_>) -> Result<Box<[CanonicalOption]>> {
.collect::<Result<_>>()
}

fn read_legacy_cancellation_byte(reader: &mut BinaryReader<'_>) -> Result<()> {
Ok(match reader.read_u8()? {
0x00 => {}
0x01 => {
return reader.invalid_leading_byte(
0x01,
"zero byte; this was historically accepted \
as `cancellable` until WebAssembly/component-model#716",
);
}
x => return reader.invalid_leading_byte(x, "zero byte"),
})
}

impl<'a> FromReader<'a> for CanonicalOption {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(match reader.read_u8()? {
Expand Down
Loading
Loading