Skip to content

Commit 81c83e5

Browse files
committed
fix stream/future type handling for exported interfaces
Signed-off-by: Joel Dice <[email protected]>
1 parent 5f4ad17 commit 81c83e5

File tree

4 files changed

+114
-42
lines changed

4 files changed

+114
-42
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ impl ComponentBuilder {
454454

455455
/// Declares a new `stream.cancel-write` intrinsic.
456456
pub fn stream_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
457-
self.canonical_functions().stream_cancel_read(ty, async_);
457+
self.canonical_functions().stream_cancel_write(ty, async_);
458458
inc(&mut self.core_funcs)
459459
}
460460

@@ -504,7 +504,7 @@ impl ComponentBuilder {
504504

505505
/// Declares a new `future.cancel-write` intrinsic.
506506
pub fn future_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
507-
self.canonical_functions().future_cancel_read(ty, async_);
507+
self.canonical_functions().future_cancel_write(ty, async_);
508508
inc(&mut self.core_funcs)
509509
}
510510

crates/wit-component/src/encoding.rs

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,7 +1320,7 @@ impl<'a> EncodingState<'a> {
13201320
.collect::<Vec<_>>(),
13211321
)
13221322
};
1323-
let type_index = self.payload_type_index(info.ty)?;
1323+
let type_index = self.payload_type_index(info.ty, info.imported)?;
13241324

13251325
match kind {
13261326
PayloadFuncKind::FutureWrite => {
@@ -1422,11 +1422,27 @@ impl<'a> EncodingState<'a> {
14221422
Ok(())
14231423
}
14241424

1425-
fn payload_type_index(&mut self, ty: TypeId) -> Result<u32> {
1425+
fn payload_type_index(&mut self, ty: TypeId, imported: bool) -> Result<u32> {
1426+
fn owner(resolve: &Resolve, ty: TypeId) -> Option<InterfaceId> {
1427+
let def = &resolve.types[ty];
1428+
match &def.kind {
1429+
TypeDefKind::Future(Some(Type::Id(ty))) => owner(resolve, *ty),
1430+
TypeDefKind::Stream(Type::Id(ty)) => owner(resolve, *ty),
1431+
_ => match &def.owner {
1432+
TypeOwner::World(_) | TypeOwner::None => None,
1433+
TypeOwner::Interface(id) => Some(*id),
1434+
},
1435+
}
1436+
}
1437+
14261438
let resolve = &self.info.encoder.metadata.resolve;
1427-
let ComponentValType::Type(type_index) = self
1428-
.root_import_type_encoder(None)
1429-
.encode_valtype(resolve, &Type::Id(ty))?
1439+
let ComponentValType::Type(type_index) = if imported {
1440+
self.root_import_type_encoder(None)
1441+
} else {
1442+
let owner = owner(resolve, ty);
1443+
self.root_export_type_encoder(owner)
1444+
}
1445+
.encode_valtype(resolve, &Type::Id(ty))?
14301446
else {
14311447
unreachable!()
14321448
};
@@ -1733,7 +1749,7 @@ impl<'a> EncodingState<'a> {
17331749
return Ok((ExportKind::Func, index));
17341750
}
17351751
Import::StreamNew(info) => {
1736-
let ty = self.payload_type_index(info.ty)?;
1752+
let ty = self.payload_type_index(info.ty, info.imported)?;
17371753
let index = self.component.stream_new(ty);
17381754
return Ok((ExportKind::Func, index));
17391755
}
@@ -1749,28 +1765,36 @@ impl<'a> EncodingState<'a> {
17491765
payload_indirect(self, *async_, info, PayloadFuncKind::StreamWrite),
17501766
));
17511767
}
1752-
Import::StreamCancelRead { ty, async_ } => {
1753-
let ty = self.payload_type_index(*ty)?;
1768+
Import::StreamCancelRead {
1769+
ty,
1770+
imported,
1771+
async_,
1772+
} => {
1773+
let ty = self.payload_type_index(*ty, *imported)?;
17541774
let index = self.component.stream_cancel_read(ty, *async_);
17551775
return Ok((ExportKind::Func, index));
17561776
}
1757-
Import::StreamCancelWrite { ty, async_ } => {
1758-
let ty = self.payload_type_index(*ty)?;
1777+
Import::StreamCancelWrite {
1778+
ty,
1779+
imported,
1780+
async_,
1781+
} => {
1782+
let ty = self.payload_type_index(*ty, *imported)?;
17591783
let index = self.component.stream_cancel_write(ty, *async_);
17601784
return Ok((ExportKind::Func, index));
17611785
}
1762-
Import::StreamCloseReadable(ty) => {
1763-
let type_index = self.payload_type_index(*ty)?;
1786+
Import::StreamCloseReadable { ty, imported } => {
1787+
let type_index = self.payload_type_index(*ty, *imported)?;
17641788
let index = self.component.stream_close_readable(type_index);
17651789
return Ok((ExportKind::Func, index));
17661790
}
1767-
Import::StreamCloseWritable(ty) => {
1768-
let type_index = self.payload_type_index(*ty)?;
1791+
Import::StreamCloseWritable { ty, imported } => {
1792+
let type_index = self.payload_type_index(*ty, *imported)?;
17691793
let index = self.component.stream_close_writable(type_index);
17701794
return Ok((ExportKind::Func, index));
17711795
}
17721796
Import::FutureNew(info) => {
1773-
let ty = self.payload_type_index(info.ty)?;
1797+
let ty = self.payload_type_index(info.ty, info.imported)?;
17741798
let index = self.component.future_new(ty);
17751799
return Ok((ExportKind::Func, index));
17761800
}
@@ -1786,23 +1810,31 @@ impl<'a> EncodingState<'a> {
17861810
payload_indirect(self, *async_, info, PayloadFuncKind::FutureWrite),
17871811
));
17881812
}
1789-
Import::FutureCancelRead { ty, async_ } => {
1790-
let ty = self.payload_type_index(*ty)?;
1813+
Import::FutureCancelRead {
1814+
ty,
1815+
imported,
1816+
async_,
1817+
} => {
1818+
let ty = self.payload_type_index(*ty, *imported)?;
17911819
let index = self.component.future_cancel_read(ty, *async_);
17921820
return Ok((ExportKind::Func, index));
17931821
}
1794-
Import::FutureCancelWrite { ty, async_ } => {
1795-
let ty = self.payload_type_index(*ty)?;
1822+
Import::FutureCancelWrite {
1823+
ty,
1824+
imported,
1825+
async_,
1826+
} => {
1827+
let ty = self.payload_type_index(*ty, *imported)?;
17961828
let index = self.component.future_cancel_write(ty, *async_);
17971829
return Ok((ExportKind::Func, index));
17981830
}
1799-
Import::FutureCloseReadable(ty) => {
1800-
let type_index = self.payload_type_index(*ty)?;
1831+
Import::FutureCloseReadable { ty, imported } => {
1832+
let type_index = self.payload_type_index(*ty, *imported)?;
18011833
let index = self.component.future_close_readable(type_index);
18021834
return Ok((ExportKind::Func, index));
18031835
}
1804-
Import::FutureCloseWritable(ty) => {
1805-
let type_index = self.payload_type_index(*ty)?;
1836+
Import::FutureCloseWritable { ty, imported } => {
1837+
let type_index = self.payload_type_index(*ty, *imported)?;
18061838
let index = self.component.future_close_writable(type_index);
18071839
return Ok((ExportKind::Func, index));
18081840
}
@@ -2160,12 +2192,12 @@ impl<'a> Shims<'a> {
21602192
| Import::StreamNew(..)
21612193
| Import::FutureCancelRead { .. }
21622194
| Import::FutureCancelWrite { .. }
2163-
| Import::FutureCloseWritable(..)
2164-
| Import::FutureCloseReadable(..)
2195+
| Import::FutureCloseWritable { .. }
2196+
| Import::FutureCloseReadable { .. }
21652197
| Import::StreamCancelRead { .. }
21662198
| Import::StreamCancelWrite { .. }
2167-
| Import::StreamCloseWritable(..)
2168-
| Import::StreamCloseReadable(..) => continue,
2199+
| Import::StreamCloseWritable { .. }
2200+
| Import::StreamCloseReadable { .. } => continue,
21692201

21702202
Import::FutureWrite { async_, info } => {
21712203
payload_push(

crates/wit-component/src/validation.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,22 @@ pub enum Import {
230230
},
231231
StreamCancelRead {
232232
ty: TypeId,
233+
imported: bool,
233234
async_: bool,
234235
},
235236
StreamCancelWrite {
236237
ty: TypeId,
238+
imported: bool,
237239
async_: bool,
238240
},
239-
StreamCloseReadable(TypeId),
240-
StreamCloseWritable(TypeId),
241+
StreamCloseReadable {
242+
ty: TypeId,
243+
imported: bool,
244+
},
245+
StreamCloseWritable {
246+
ty: TypeId,
247+
imported: bool,
248+
},
241249
FutureNew(PayloadInfo),
242250
FutureRead {
243251
async_: bool,
@@ -249,14 +257,22 @@ pub enum Import {
249257
},
250258
FutureCancelRead {
251259
ty: TypeId,
260+
imported: bool,
252261
async_: bool,
253262
},
254263
FutureCancelWrite {
255264
ty: TypeId,
265+
imported: bool,
256266
async_: bool,
257267
},
258-
FutureCloseReadable(TypeId),
259-
FutureCloseWritable(TypeId),
268+
FutureCloseReadable {
269+
ty: TypeId,
270+
imported: bool,
271+
},
272+
FutureCloseWritable {
273+
ty: TypeId,
274+
imported: bool,
275+
},
260276
ErrorContextNew {
261277
encoding: StringEncoding,
262278
},
@@ -1464,34 +1480,46 @@ impl NameMangling for Legacy {
14641480
&FuncType::new([ValType::I32], [ValType::I32]),
14651481
ty,
14661482
)?;
1483+
let info = info(key)?;
14671484
Import::FutureCancelWrite {
14681485
async_,
1469-
ty: info(key)?.ty,
1486+
ty: info.ty,
1487+
imported: info.imported,
14701488
}
14711489
} else if let Some(key) = match_payload_prefix(name, "[future-cancel-read-") {
14721490
validate_func_sig(
14731491
name,
14741492
&FuncType::new([ValType::I32], [ValType::I32]),
14751493
ty,
14761494
)?;
1495+
let info = info(key)?;
14771496
Import::FutureCancelRead {
14781497
async_,
1479-
ty: info(key)?.ty,
1498+
ty: info.ty,
1499+
imported: info.imported,
14801500
}
14811501
} else if let Some(key) = match_payload_prefix(name, "[future-close-writable-")
14821502
{
14831503
if async_ {
14841504
bail!("async `future.close-writable` calls not supported");
14851505
}
14861506
validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?;
1487-
Import::FutureCloseWritable(info(key)?.ty)
1507+
let info = info(key)?;
1508+
Import::FutureCloseWritable {
1509+
ty: info.ty,
1510+
imported: info.imported,
1511+
}
14881512
} else if let Some(key) = match_payload_prefix(name, "[future-close-readable-")
14891513
{
14901514
if async_ {
14911515
bail!("async `future.close-readable` calls not supported");
14921516
}
14931517
validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?;
1494-
Import::FutureCloseReadable(info(key)?.ty)
1518+
let info = info(key)?;
1519+
Import::FutureCloseReadable {
1520+
ty: info.ty,
1521+
imported: info.imported,
1522+
}
14951523
} else if let Some(key) = match_payload_prefix(name, "[stream-new-") {
14961524
if async_ {
14971525
bail!("async `stream.new` calls not supported");
@@ -1524,34 +1552,46 @@ impl NameMangling for Legacy {
15241552
&FuncType::new([ValType::I32], [ValType::I32]),
15251553
ty,
15261554
)?;
1555+
let info = info(key)?;
15271556
Import::StreamCancelWrite {
15281557
async_,
1529-
ty: info(key)?.ty,
1558+
ty: info.ty,
1559+
imported: info.imported,
15301560
}
15311561
} else if let Some(key) = match_payload_prefix(name, "[stream-cancel-read-") {
15321562
validate_func_sig(
15331563
name,
15341564
&FuncType::new([ValType::I32], [ValType::I32]),
15351565
ty,
15361566
)?;
1567+
let info = info(key)?;
15371568
Import::StreamCancelRead {
15381569
async_,
1539-
ty: info(key)?.ty,
1570+
ty: info.ty,
1571+
imported: info.imported,
15401572
}
15411573
} else if let Some(key) = match_payload_prefix(name, "[stream-close-writable-")
15421574
{
15431575
if async_ {
15441576
bail!("async `stream.close-writable` calls not supported");
15451577
}
15461578
validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?;
1547-
Import::StreamCloseWritable(info(key)?.ty)
1579+
let info = info(key)?;
1580+
Import::StreamCloseWritable {
1581+
ty: info.ty,
1582+
imported: info.imported,
1583+
}
15481584
} else if let Some(key) = match_payload_prefix(name, "[stream-close-readable-")
15491585
{
15501586
if async_ {
15511587
bail!("async `stream.close-readable` calls not supported");
15521588
}
15531589
validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?;
1554-
Import::StreamCloseReadable(info(key)?.ty)
1590+
let info = info(key)?;
1591+
Import::StreamCloseReadable {
1592+
ty: info.ty,
1593+
imported: info.imported,
1594+
}
15551595
} else {
15561596
bail!("unrecognized payload import: {name}");
15571597
},

crates/wit-component/tests/components.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fn run_test(path: &Path) -> Result<()> {
157157
WasmFeatures::WASM2 | WasmFeatures::COMPONENT_MODEL | WasmFeatures::COMPONENT_MODEL_ASYNC;
158158
Validator::new_with_features(features)
159159
.validate_all(&bytes)
160-
.context("failed to validated component output")?;
160+
.context("failed to validate component output")?;
161161

162162
let wat = wasmprinter::print_bytes(&bytes).context("failed to print bytes")?;
163163
assert_output(&wat, &component_path)?;

0 commit comments

Comments
 (0)