Skip to content

Commit 4e37f73

Browse files
authored
update task.return to match spec (#1989)
* update `task.return` to match spec As of WebAssembly/component-model#431, `task.return` takes component-level result types rather than a core function type representing the flattening of those types. This updates `wasm-tools` to match. Signed-off-by: Joel Dice <[email protected]> * remove `task.return` support for named results Signed-off-by: Joel Dice <[email protected]> * add assertion to `ComponentState::task_return` Signed-off-by: Joel Dice <[email protected]> --------- Signed-off-by: Joel Dice <[email protected]>
1 parent 17220b6 commit 4e37f73

File tree

18 files changed

+143
-114
lines changed

18 files changed

+143
-114
lines changed

crates/wasm-encoder/src/component/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ impl ComponentBuilder {
392392
}
393393

394394
/// Declares a new `task.return` intrinsic.
395-
pub fn task_return(&mut self, ty: u32) -> u32 {
395+
pub fn task_return(&mut self, ty: Option<impl Into<ComponentValType>>) -> u32 {
396396
self.canonical_functions().task_return(ty);
397397
inc(&mut self.core_funcs)
398398
}

crates/wasm-encoder/src/component/canonicals.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{encode_section, ComponentSection, ComponentSectionId, Encode};
1+
use crate::{encode_section, ComponentSection, ComponentSectionId, ComponentValType, Encode};
22
use alloc::vec::Vec;
33

44
/// Represents options for canonical function definitions.
@@ -188,9 +188,15 @@ impl CanonicalFunctionSection {
188188
/// Defines a function which returns a result to the caller of a lifted
189189
/// export function. This allows the callee to continue executing after
190190
/// returning a result.
191-
pub fn task_return(&mut self, ty: u32) -> &mut Self {
191+
pub fn task_return(&mut self, ty: Option<impl Into<ComponentValType>>) -> &mut Self {
192192
self.bytes.push(0x09);
193-
ty.encode(&mut self.bytes);
193+
if let Some(ty) = ty {
194+
self.bytes.push(0x00);
195+
ty.into().encode(&mut self.bytes);
196+
} else {
197+
self.bytes.push(0x01);
198+
0_usize.encode(&mut self.bytes);
199+
}
194200
self.num_added += 1;
195201
self
196202
}

crates/wasm-encoder/src/reencode/component.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,8 +970,8 @@ pub mod component_utils {
970970
wasmparser::CanonicalFunction::TaskBackpressure => {
971971
section.task_backpressure();
972972
}
973-
wasmparser::CanonicalFunction::TaskReturn { type_index } => {
974-
section.task_return(reencoder.type_index(type_index));
973+
wasmparser::CanonicalFunction::TaskReturn { result } => {
974+
section.task_return(result.map(|ty| reencoder.component_val_type(ty)));
975975
}
976976
wasmparser::CanonicalFunction::TaskWait { async_, memory } => {
977977
section.task_wait(async_, reencoder.memory_index(memory));

crates/wasmparser/src/readers/component/canonicals.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::limits::MAX_WASM_CANONICAL_OPTIONS;
22
use crate::prelude::*;
3-
use crate::{BinaryReader, FromReader, Result, SectionLimited};
3+
use crate::{
4+
BinaryReader, BinaryReaderError, ComponentValType, FromReader, Result, SectionLimited,
5+
};
46

57
/// Represents options for component functions.
68
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -80,10 +82,8 @@ pub enum CanonicalFunction {
8082
/// function. This allows the callee to continue executing after returning
8183
/// a result.
8284
TaskReturn {
83-
/// Core function type whose parameters represent the flattened
84-
/// representation of the component-level results to be returned by the
85-
/// currently executing task.
86-
type_index: u32,
85+
/// The result type, if any.
86+
result: Option<ComponentValType>,
8787
},
8888
/// A function which waits for at least one outstanding async
8989
/// task/stream/future to make progress, returning the first such event.
@@ -275,7 +275,20 @@ impl<'a> FromReader<'a> for CanonicalFunction {
275275
0x06 => CanonicalFunction::ThreadHwConcurrency,
276276
0x08 => CanonicalFunction::TaskBackpressure,
277277
0x09 => CanonicalFunction::TaskReturn {
278-
type_index: reader.read()?,
278+
result: match reader.read_u8()? {
279+
0x00 => Some(reader.read()?),
280+
0x01 => {
281+
if reader.read_u8()? == 0 {
282+
None
283+
} else {
284+
return Err(BinaryReaderError::new(
285+
"named results not allowed for `task.return` intrinsic",
286+
reader.original_position() - 2,
287+
));
288+
}
289+
}
290+
x => return reader.invalid_leading_byte(x, "`task.return` result"),
291+
},
279292
},
280293
0x0a => CanonicalFunction::TaskWait {
281294
async_: reader.read()?,

crates/wasmparser/src/validator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,8 +1313,8 @@ impl Validator {
13131313
crate::CanonicalFunction::TaskBackpressure => {
13141314
current.task_backpressure(types, offset, features)
13151315
}
1316-
crate::CanonicalFunction::TaskReturn { type_index } => {
1317-
current.task_return(type_index, types, offset, features)
1316+
crate::CanonicalFunction::TaskReturn { result } => {
1317+
current.task_return(&result, types, offset, features)
13181318
}
13191319
crate::CanonicalFunction::TaskWait { async_, memory } => {
13201320
current.task_wait(async_, memory, types, offset, features)

crates/wasmparser/src/validator/component.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ use crate::prelude::*;
1919
use crate::validator::names::{ComponentName, ComponentNameKind, KebabStr, KebabString};
2020
use crate::{
2121
BinaryReaderError, CanonicalOption, ComponentExportName, ComponentExternalKind,
22-
ComponentOuterAliasKind, ComponentTypeRef, CompositeInnerType, CompositeType, ExternalKind,
23-
FuncType, GlobalType, InstantiationArgKind, MemoryType, PackedIndex, RefType, Result, SubType,
24-
TableType, TypeBounds, ValType, WasmFeatures,
22+
ComponentOuterAliasKind, ComponentTypeRef, CompositeInnerType, ExternalKind, FuncType,
23+
GlobalType, InstantiationArgKind, MemoryType, PackedIndex, RefType, Result, SubType, TableType,
24+
TypeBounds, ValType, WasmFeatures,
2525
};
2626
use core::mem;
2727

@@ -1102,7 +1102,7 @@ impl ComponentState {
11021102

11031103
pub fn task_return(
11041104
&mut self,
1105-
type_index: u32,
1105+
result: &Option<crate::ComponentValType>,
11061106
types: &mut TypeAlloc,
11071107
offset: usize,
11081108
features: &WasmFeatures,
@@ -1114,20 +1114,32 @@ impl ComponentState {
11141114
)
11151115
}
11161116

1117-
let id = self.type_id_at(type_index, offset)?;
1118-
let Some(SubType {
1119-
composite_type:
1120-
CompositeType {
1121-
inner: CompositeInnerType::Func(_),
1122-
..
1123-
},
1124-
..
1125-
}) = types.get(id)
1126-
else {
1127-
bail!(offset, "invalid `task.return` type index");
1128-
};
1117+
let info = ComponentFuncType {
1118+
info: TypeInfo::new(),
1119+
params: result
1120+
.iter()
1121+
.map(|ty| {
1122+
Ok((
1123+
KebabString::new("v").unwrap(),
1124+
match ty {
1125+
crate::ComponentValType::Primitive(ty) => {
1126+
ComponentValType::Primitive(*ty)
1127+
}
1128+
crate::ComponentValType::Type(index) => {
1129+
ComponentValType::Type(self.defined_type_at(*index, offset)?)
1130+
}
1131+
},
1132+
))
1133+
})
1134+
.collect::<Result<_>>()?,
1135+
results: Box::new([]),
1136+
}
1137+
.lower(types, Abi::LiftSync);
11291138

1130-
self.core_funcs.push(id);
1139+
assert!(info.results.iter().next().is_none());
1140+
1141+
self.core_funcs
1142+
.push(types.intern_func_type(FuncType::new(info.params.iter(), []), offset));
11311143
Ok(())
11321144
}
11331145

crates/wasmprinter/src/component.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -914,9 +914,15 @@ impl Printer<'_, '_> {
914914
CanonicalFunction::TaskBackpressure => {
915915
self.print_intrinsic(state, "canon task.backpressure", &|_, _| Ok(()))?;
916916
}
917-
CanonicalFunction::TaskReturn { type_index } => {
918-
self.print_intrinsic(state, "canon task.return ", &|me, state| {
919-
me.print_idx(&state.component.type_names, type_index)
917+
CanonicalFunction::TaskReturn { result } => {
918+
self.print_intrinsic(state, "canon task.return", &|me, state| {
919+
if let Some(ty) = result {
920+
me.result.write_str(" ")?;
921+
me.start_group("result ")?;
922+
me.print_component_val_type(state, &ty)?;
923+
me.end_group()?;
924+
}
925+
Ok(())
920926
})?;
921927
}
922928
CanonicalFunction::TaskWait { async_, memory } => {

crates/wast/src/component/binary.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,11 @@ impl<'a> Encoder<'a> {
363363
}
364364
CanonicalFuncKind::TaskReturn(info) => {
365365
self.core_func_names.push(name);
366-
self.funcs.task_return(info.ty.into());
366+
self.funcs.task_return(
367+
info.result
368+
.as_ref()
369+
.map(|ty| wasm_encoder::ComponentValType::from(ty)),
370+
);
367371
}
368372
CanonicalFuncKind::TaskWait(info) => {
369373
self.core_func_names.push(name);

crates/wast/src/component/func.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -521,17 +521,24 @@ impl<'a> Parse<'a> for CanonThreadHwConcurrency {
521521
/// Information relating to the `task.return` intrinsic.
522522
#[derive(Debug)]
523523
pub struct CanonTaskReturn<'a> {
524-
/// The core function type representing the signature of this intrinsic.
525-
pub ty: Index<'a>,
524+
/// The type of the result which may be returned with this intrinsic.
525+
pub result: Option<ComponentValType<'a>>,
526526
}
527527

528528
impl<'a> Parse<'a> for CanonTaskReturn<'a> {
529529
fn parse(parser: Parser<'a>) -> Result<Self> {
530530
parser.parse::<kw::task_return>()?;
531531

532-
Ok(Self {
533-
ty: parser.parse()?,
534-
})
532+
let result = if parser.peek2::<kw::result>()? {
533+
Some(parser.parens(|p| {
534+
p.parse::<kw::result>()?.0;
535+
p.parse()
536+
})?)
537+
} else {
538+
None
539+
};
540+
541+
Ok(Self { result })
535542
}
536543
}
537544

crates/wast/src/component/resolve.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,9 @@ impl<'a> Resolver<'a> {
392392
| CanonicalFuncKind::SubtaskDrop
393393
| CanonicalFuncKind::ErrorContextDrop => {}
394394
CanonicalFuncKind::TaskReturn(info) => {
395-
self.resolve_ns(&mut info.ty, Ns::CoreType)?;
395+
if let Some(ty) = &mut info.result {
396+
self.component_val_type(ty)?;
397+
}
396398
}
397399
CanonicalFuncKind::TaskWait(info) => {
398400
self.core_item_ref(&mut info.memory)?;

0 commit comments

Comments
 (0)