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
38 changes: 26 additions & 12 deletions crates/wasm-encoder/src/component/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,10 +708,17 @@ impl ComponentBuilder {
self.core_funcs.add(Some("thread.new-indirect"))
}

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

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

/// Declares a new `thread.suspend` intrinsic.
Expand All @@ -720,16 +727,23 @@ impl ComponentBuilder {
self.core_funcs.add(Some("thread.suspend"))
}

/// Declares a new `thread.resume-later` intrinsic.
pub fn thread_resume_later(&mut self) -> u32 {
self.canonical_functions().thread_resume_later();
self.core_funcs.add(Some("thread.resume-later"))
/// Declares a new `thread.unsuspend` intrinsic.
pub fn thread_unsuspend(&mut self) -> u32 {
self.canonical_functions().thread_unsuspend();
self.core_funcs.add(Some("thread.unsuspend"))
}

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

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

/// Adds a new custom section to this component.
Expand Down
32 changes: 24 additions & 8 deletions crates/wasm-encoder/src/component/canonicals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,9 +522,9 @@ impl CanonicalFunctionSection {
self
}

/// Declare a new `thread.switch-to` intrinsic, used to switch execution to
/// another thread.
pub fn thread_switch_to(&mut self, cancellable: bool) -> &mut Self {
/// Declare a new `thread.suspend-to-suspended` intrinsic, used to switch execution to
/// another suspended thread.
pub fn thread_suspend_to_suspended(&mut self, cancellable: bool) -> &mut Self {
self.bytes.push(0x28);
self.bytes.push(if cancellable { 1 } else { 0 });
self.num_added += 1;
Expand All @@ -540,23 +540,39 @@ impl CanonicalFunctionSection {
self
}

/// Declare a new `thread.resume-later` intrinsic, used to resume execution
/// Declare a new `thread.suspend-to` intrinsic, used to suspend the current
/// thread and switch to another thread that might not be suspended.
pub fn thread_suspend_to(&mut self, cancellable: bool) -> &mut Self {
self.bytes.push(0x2c);
self.bytes.push(if cancellable { 1 } else { 0 });
self.num_added += 1;
self
}

/// Declare a new `thread.unsuspend` intrinsic, used to resume execution
/// of the given thread.
pub fn thread_resume_later(&mut self) -> &mut Self {
pub fn thread_unsuspend(&mut self) -> &mut Self {
self.bytes.push(0x2a);
self.num_added += 1;
self
}

/// Declare a new `thread.yield-to` intrinsic, used to yield execution to
/// a given thread.
pub fn thread_yield_to(&mut self, cancellable: bool) -> &mut Self {
/// Declare a new `thread.yield-to-suspended` intrinsic, used to yield execution to
/// a given suspended thread.
pub fn thread_yield_to_suspended(&mut self, cancellable: bool) -> &mut Self {
self.bytes.push(0x2b);
self.bytes.push(if cancellable { 1 } else { 0 });
self.num_added += 1;
self
}

/// Declare a new `thread.exit` intrinsic, used to terminate the current thread.
pub fn thread_exit(&mut self) -> &mut Self {
self.bytes.push(0x2d);
self.num_added += 1;
self
}

fn encode_options<O>(&mut self, options: O) -> &mut Self
where
O: IntoIterator<Item = CanonicalOption>,
Expand Down
18 changes: 12 additions & 6 deletions crates/wasm-encoder/src/reencode/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1121,17 +1121,23 @@ pub mod component_utils {
let table_index = reencoder.table_index(table_index)?;
section.thread_new_indirect(func_ty, table_index);
}
wasmparser::CanonicalFunction::ThreadSwitchTo { cancellable } => {
section.thread_switch_to(cancellable);
wasmparser::CanonicalFunction::ThreadSuspendToSuspended { cancellable } => {
section.thread_suspend_to_suspended(cancellable);
}
wasmparser::CanonicalFunction::ThreadSuspend { cancellable } => {
section.thread_suspend(cancellable);
}
wasmparser::CanonicalFunction::ThreadResumeLater => {
section.thread_resume_later();
wasmparser::CanonicalFunction::ThreadSuspendTo { cancellable } => {
section.thread_suspend_to(cancellable);
}
wasmparser::CanonicalFunction::ThreadYieldTo { cancellable } => {
section.thread_yield_to(cancellable);
wasmparser::CanonicalFunction::ThreadUnsuspend => {
section.thread_unsuspend();
}
wasmparser::CanonicalFunction::ThreadYieldToSuspended { cancellable } => {
section.thread_yield_to_suspended(cancellable);
}
wasmparser::CanonicalFunction::ThreadExit => {
section.thread_exit();
}
}
Ok(())
Expand Down
27 changes: 19 additions & 8 deletions crates/wasmparser/src/readers/component/canonicals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ pub enum CanonicalFunction {
/// The index of the table to use.
table_index: u32,
},
/// A function to suspend the current thread and switch to the given thread.
ThreadSwitchTo {
/// A function to suspend the current thread and switch to the given suspended thread.
ThreadSuspendToSuspended {
/// Whether or not the thread can be cancelled while awaiting resumption.
cancellable: bool,
},
Expand All @@ -284,13 +284,20 @@ pub enum CanonicalFunction {
/// Whether or not the thread can be cancelled while suspended.
cancellable: bool,
},
/// A function to suspend the current thread and switch to another thread.
ThreadSuspendTo {
/// Whether or not the thread can be cancelled while suspended.
cancellable: bool,
},
/// A function to schedule the given thread to be resumed later.
ThreadResumeLater,
/// A function to suspend the current thread and switch to the given thread.
ThreadYieldTo {
ThreadUnsuspend,
/// A function to yield to the given suspended thread.
ThreadYieldToSuspended {
/// Whether or not the thread can be cancelled while yielding.
cancellable: bool,
},
/// A function to terminate the current thread.
ThreadExit,
}

/// A reader for the canonical section of a WebAssembly component.
Expand Down Expand Up @@ -406,16 +413,20 @@ impl<'a> FromReader<'a> for CanonicalFunction {
func_ty_index: reader.read()?,
table_index: reader.read()?,
},
0x28 => CanonicalFunction::ThreadSwitchTo {
0x28 => CanonicalFunction::ThreadSuspendToSuspended {
cancellable: reader.read()?,
},
0x29 => CanonicalFunction::ThreadSuspend {
cancellable: reader.read()?,
},
0x2a => CanonicalFunction::ThreadResumeLater,
0x2b => CanonicalFunction::ThreadYieldTo {
0x2a => CanonicalFunction::ThreadUnsuspend,
0x2b => CanonicalFunction::ThreadYieldToSuspended {
cancellable: reader.read()?,
},
0x2c => CanonicalFunction::ThreadSuspendTo {
cancellable: reader.read()?,
},
0x2d => CanonicalFunction::ThreadExit,
0x06 => CanonicalFunction::SubtaskCancel {
async_: reader.read()?,
},
Expand Down
56 changes: 44 additions & 12 deletions crates/wasmparser/src/validator/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1264,17 +1264,20 @@ impl ComponentState {
func_ty_index,
table_index,
} => self.thread_new_indirect(func_ty_index, table_index, types, offset),
CanonicalFunction::ThreadSwitchTo { cancellable } => {
self.thread_switch_to(cancellable, types, offset)
CanonicalFunction::ThreadSuspendToSuspended { cancellable } => {
self.thread_suspend_to_suspended(cancellable, types, offset)
}
CanonicalFunction::ThreadSuspend { cancellable } => {
self.thread_suspend(cancellable, types, offset)
}
CanonicalFunction::ThreadResumeLater => self.thread_resume_later(types, offset),

CanonicalFunction::ThreadYieldTo { cancellable } => {
self.thread_yield_to(cancellable, types, offset)
CanonicalFunction::ThreadSuspendTo { cancellable } => {
self.thread_suspend_to(cancellable, types, offset)
}
CanonicalFunction::ThreadUnsuspend => self.thread_unsuspend(types, offset),
CanonicalFunction::ThreadYieldToSuspended { cancellable } => {
self.thread_yield_to_suspended(cancellable, types, offset)
}
CanonicalFunction::ThreadExit => self.thread_exit(types, offset),
}
}

Expand Down Expand Up @@ -2203,7 +2206,7 @@ impl ComponentState {
Ok(())
}

fn thread_switch_to(
fn thread_suspend_to_suspended(
&mut self,
_cancellable: bool,
types: &mut TypeAlloc,
Expand All @@ -2212,7 +2215,7 @@ impl ComponentState {
if !self.features.cm_threading() {
bail!(
offset,
"`thread.switch_to` requires the component model threading feature"
"`thread.suspend_to_suspended` requires the component model threading feature"
)
}

Expand All @@ -2238,19 +2241,36 @@ impl ComponentState {
Ok(())
}

fn thread_resume_later(&mut self, types: &mut TypeAlloc, offset: usize) -> Result<()> {
fn thread_suspend_to(
&mut self,
_cancellable: bool,
types: &mut TypeAlloc,
offset: usize,
) -> Result<()> {
if !self.features.cm_threading() {
bail!(
offset,
"`thread.resume_later` requires the component model threading feature"
"`thread.suspend_to` requires the component model threading feature"
)
}
self.core_funcs
.push(types.intern_func_type(FuncType::new([ValType::I32], [ValType::I32]), offset));
Ok(())
}

fn thread_unsuspend(&mut self, types: &mut TypeAlloc, offset: usize) -> Result<()> {
if !self.features.cm_threading() {
bail!(
offset,
"`thread.unsuspend` requires the component model threading feature"
)
}
self.core_funcs
.push(types.intern_func_type(FuncType::new([ValType::I32], []), offset));
Ok(())
}

fn thread_yield_to(
fn thread_yield_to_suspended(
&mut self,
_cancellable: bool,
types: &mut TypeAlloc,
Expand All @@ -2259,14 +2279,26 @@ impl ComponentState {
if !self.features.cm_threading() {
bail!(
offset,
"`thread.yield_to` requires the component model threading feature"
"`thread.yield_to_suspended` requires the component model threading feature"
)
}
self.core_funcs
.push(types.intern_func_type(FuncType::new([ValType::I32], [ValType::I32]), offset));
Ok(())
}

fn thread_exit(&mut self, types: &mut TypeAlloc, offset: usize) -> Result<()> {
if !self.features.cm_threading() {
bail!(
offset,
"`thread.exit` requires the component model threading feature"
)
}
self.core_funcs
.push(types.intern_func_type(FuncType::new([], []), offset));
Ok(())
}

fn check_local_resource(&self, idx: u32, types: &TypeList, offset: usize) -> Result<ValType> {
let resource = self.resource_at(idx, types, offset)?;
match self
Expand Down
23 changes: 17 additions & 6 deletions crates/wasmprinter/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1169,8 +1169,8 @@ impl Printer<'_, '_> {
me.end_group()
})?;
}
CanonicalFunction::ThreadSwitchTo { cancellable } => {
self.print_intrinsic(state, "canon thread.switch-to", &|me, _| {
CanonicalFunction::ThreadSuspendToSuspended { cancellable } => {
self.print_intrinsic(state, "canon thread.suspend-to-suspended", &|me, _| {
if cancellable {
me.result.write_str(" cancellable")?;
}
Expand All @@ -1185,17 +1185,28 @@ impl Printer<'_, '_> {
Ok(())
})?;
}
CanonicalFunction::ThreadResumeLater => {
self.print_intrinsic(state, "canon thread.resume-later", &|_, _| Ok(()))?;
CanonicalFunction::ThreadSuspendTo { cancellable } => {
self.print_intrinsic(state, "canon thread.suspend-to", &|me, _| {
if cancellable {
me.result.write_str(" cancellable")?;
}
Ok(())
})?;
}
CanonicalFunction::ThreadUnsuspend => {
self.print_intrinsic(state, "canon thread.unsuspend", &|_, _| Ok(()))?;
}
CanonicalFunction::ThreadYieldTo { cancellable } => {
self.print_intrinsic(state, "canon thread.yield-to", &|me, _| {
CanonicalFunction::ThreadYieldToSuspended { cancellable } => {
self.print_intrinsic(state, "canon thread.yield-to-suspended", &|me, _| {
if cancellable {
me.result.write_str(" cancellable")?;
}
Ok(())
})?;
}
CanonicalFunction::ThreadExit => {
self.print_intrinsic(state, "canon thread.exit", &|_, _| Ok(()))?;
}
}
}

Expand Down
20 changes: 14 additions & 6 deletions crates/wast/src/component/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,21 +519,29 @@ impl<'a> Encoder<'a> {
self.funcs
.thread_new_indirect(info.ty.into(), info.table.idx.into());
}
CoreFuncKind::ThreadSwitchTo(info) => {
CoreFuncKind::ThreadSuspendToSuspended(info) => {
self.core_func_names.push(name);
self.funcs.thread_switch_to(info.cancellable);
self.funcs.thread_suspend_to_suspended(info.cancellable);
}
CoreFuncKind::ThreadSuspend(info) => {
self.core_func_names.push(name);
self.funcs.thread_suspend(info.cancellable);
}
CoreFuncKind::ThreadResumeLater => {
CoreFuncKind::ThreadSuspendTo(info) => {
self.core_func_names.push(name);
self.funcs.thread_resume_later();
self.funcs.thread_suspend_to(info.cancellable);
}
CoreFuncKind::ThreadYieldTo(info) => {
CoreFuncKind::ThreadUnsuspend => {
self.core_func_names.push(name);
self.funcs.thread_yield_to(info.cancellable);
self.funcs.thread_unsuspend();
}
CoreFuncKind::ThreadYieldToSuspended(info) => {
self.core_func_names.push(name);
self.funcs.thread_yield_to_suspended(info.cancellable);
}
CoreFuncKind::ThreadExit => {
self.core_func_names.push(name);
self.funcs.thread_exit();
}
},
}
Expand Down
Loading
Loading