Skip to content

Commit b99bbd4

Browse files
committed
address stream and future TODOs
Signed-off-by: Joel Dice <[email protected]>
1 parent 47465de commit b99bbd4

File tree

2 files changed

+403
-86
lines changed

2 files changed

+403
-86
lines changed

crates/wit-component/src/encoding.rs

Lines changed: 278 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
//! component model.
7373
7474
use crate::metadata::{self, Bindgen, ModuleMetadata};
75-
use crate::validation::{Export, ExportMap, Import, ImportInstance, ImportMap};
75+
use crate::validation::{Export, ExportMap, Import, ImportInstance, ImportMap, PayloadInfo};
7676
use crate::StringEncoding;
7777
use anyhow::{anyhow, bail, Context, Result};
7878
use indexmap::{IndexMap, IndexSet};
@@ -84,8 +84,8 @@ use wasm_encoder::*;
8484
use wasmparser::Validator;
8585
use wit_parser::{
8686
abi::{AbiVariant, WasmSignature, WasmType},
87-
Function, FunctionKind, InterfaceId, LiveTypes, Resolve, Type, TypeDefKind, TypeId, TypeOwner,
88-
WorldItem, WorldKey,
87+
Function, FunctionKind, InterfaceId, LiveTypes, Resolve, Results, Stability, Type, TypeDefKind,
88+
TypeId, TypeOwner, WorldItem, WorldKey,
8989
};
9090

9191
const INDIRECT_TABLE_NAME: &str = "$imports";
@@ -1271,13 +1271,110 @@ impl<'a> EncodingState<'a> {
12711271

12721272
ShimKind::PayloadFunc {
12731273
for_module,
1274-
module,
1275-
imported,
1276-
function,
1277-
ordinal,
1274+
info,
12781275
kind,
12791276
} => {
1280-
todo!()
1277+
let metadata = self.info.module_metadata_for(*for_module);
1278+
let exports = self.info.exports_for(*for_module);
1279+
let instance_index = self.instance_for(*for_module);
1280+
let (encoding, realloc) = if info.imported {
1281+
(
1282+
metadata
1283+
.import_encodings
1284+
.get(resolve, &info.key, &info.function.name),
1285+
exports.export_realloc_for(&info.key, &info.function),
1286+
)
1287+
} else {
1288+
(
1289+
metadata
1290+
.export_encodings
1291+
.get(resolve, &info.key, &info.function.name),
1292+
exports.import_realloc_for(info.interface, &info.function.name),
1293+
)
1294+
};
1295+
let encoding = encoding.unwrap_or(StringEncoding::UTF8);
1296+
let realloc_index = realloc
1297+
.map(|name| self.core_alias_export(instance_index, name, ExportKind::Func));
1298+
let options = |me: &mut Self, params: Vec<Type>, results: Vec<Type>| {
1299+
Ok::<_, anyhow::Error>(
1300+
(RequiredOptions::for_import(
1301+
resolve,
1302+
&Function {
1303+
name: String::new(),
1304+
kind: FunctionKind::Freestanding,
1305+
params: params
1306+
.into_iter()
1307+
.enumerate()
1308+
.map(|(i, v)| (format!("a{i}"), v))
1309+
.collect(),
1310+
results: match &results[..] {
1311+
[] => Results::Named(Vec::new()),
1312+
[ty] => Results::Anon(*ty),
1313+
_ => unreachable!(),
1314+
},
1315+
docs: Default::default(),
1316+
stability: Stability::Unknown,
1317+
},
1318+
AbiVariant::GuestImportAsync,
1319+
) & !RequiredOptions::ASYNC)
1320+
.into_iter(encoding, me.memory_index, realloc_index)?
1321+
.collect::<Vec<_>>(),
1322+
)
1323+
};
1324+
let type_index = self.payload_type_index(info.ty)?;
1325+
1326+
match kind {
1327+
PayloadFuncKind::FutureNew => self
1328+
.component
1329+
.future_new(type_index, self.memory_index.unwrap()),
1330+
PayloadFuncKind::FutureSend => {
1331+
let TypeDefKind::Future(payload_type) = &resolve.types[info.ty].kind
1332+
else {
1333+
unreachable!()
1334+
};
1335+
let options = options(
1336+
self,
1337+
if let Some(payload_type) = payload_type {
1338+
vec![Type::U32, *payload_type]
1339+
} else {
1340+
vec![Type::U32]
1341+
},
1342+
vec![Type::Id(unit_result.unwrap())],
1343+
)?;
1344+
self.component.future_send(type_index, options)
1345+
}
1346+
PayloadFuncKind::FutureReceive => {
1347+
let options = options(
1348+
self,
1349+
vec![Type::U32],
1350+
vec![Type::Id(payload_results[&info.ty])],
1351+
)?;
1352+
self.component.future_receive(type_index, options)
1353+
}
1354+
PayloadFuncKind::StreamNew => self
1355+
.component
1356+
.stream_new(type_index, self.memory_index.unwrap()),
1357+
PayloadFuncKind::StreamSend => {
1358+
let TypeDefKind::Stream(payload_type) = &resolve.types[info.ty].kind
1359+
else {
1360+
unreachable!()
1361+
};
1362+
let options = options(
1363+
self,
1364+
vec![Type::U32, *payload_type],
1365+
vec![Type::Id(unit_result.unwrap())],
1366+
)?;
1367+
self.component.stream_send(type_index, options)
1368+
}
1369+
PayloadFuncKind::StreamReceive => {
1370+
let options = options(
1371+
self,
1372+
vec![Type::Id(info.ty)],
1373+
vec![Type::Id(payload_results[&info.ty])],
1374+
)?;
1375+
self.component.stream_receive(type_index, options)
1376+
}
1377+
}
12811378
}
12821379

12831380
ShimKind::TaskWait => self.component.task_wait(self.memory_index.unwrap()),
@@ -1294,6 +1391,17 @@ impl<'a> EncodingState<'a> {
12941391
Ok(())
12951392
}
12961393

1394+
fn payload_type_index(&mut self, ty: TypeId) -> Result<u32> {
1395+
let resolve = &self.info.encoder.metadata.resolve;
1396+
let ComponentValType::Type(type_index) = self
1397+
.root_import_type_encoder(None)
1398+
.encode_valtype(resolve, &Type::Id(ty))?
1399+
else {
1400+
unreachable!()
1401+
};
1402+
Ok(type_index)
1403+
}
1404+
12971405
/// This is a helper function that will declare, in the component itself,
12981406
/// all exported resources.
12991407
///
@@ -1439,6 +1547,18 @@ impl<'a> EncodingState<'a> {
14391547
) -> Result<(ExportKind, u32)> {
14401548
log::trace!("attempting to materialize import of `{module}::{field}` for {for_module:?}");
14411549
let resolve = &self.info.encoder.metadata.resolve;
1550+
let payload_indirect = |me: &mut Self, info, kind| {
1551+
me.component.core_alias_export(
1552+
me.shim_instance_index.expect("shim should be instantiated"),
1553+
&shims.shims[&ShimKind::PayloadFunc {
1554+
for_module,
1555+
info,
1556+
kind,
1557+
}]
1558+
.name,
1559+
ExportKind::Func,
1560+
)
1561+
};
14421562
let name_tmp;
14431563
let (key, name, interface_key, abi) = match import {
14441564
// Main module dependencies on an adapter in use are done with an
@@ -1531,16 +1651,62 @@ impl<'a> EncodingState<'a> {
15311651
);
15321652
return Ok((ExportKind::Func, index));
15331653
}
1534-
Import::FutureNew(_) => todo!(),
1535-
Import::FutureSend(_) => todo!(),
1536-
Import::FutureReceive(_) => todo!(),
1537-
Import::FutureDropSender(_) => todo!(),
1538-
Import::FutureDropReceiver(_) => todo!(),
1539-
Import::StreamNew(_) => todo!(),
1540-
Import::StreamSend(_) => todo!(),
1541-
Import::StreamReceive(_) => todo!(),
1542-
Import::StreamDropSender(_) => todo!(),
1543-
Import::StreamDropReceiver(_) => todo!(),
1654+
Import::FutureNew(info) => {
1655+
return Ok((
1656+
ExportKind::Func,
1657+
payload_indirect(self, info, PayloadFuncKind::FutureNew),
1658+
));
1659+
}
1660+
Import::FutureSend(info) => {
1661+
return Ok((
1662+
ExportKind::Func,
1663+
payload_indirect(self, info, PayloadFuncKind::FutureSend),
1664+
));
1665+
}
1666+
Import::FutureReceive(info) => {
1667+
return Ok((
1668+
ExportKind::Func,
1669+
payload_indirect(self, info, PayloadFuncKind::FutureReceive),
1670+
));
1671+
}
1672+
Import::FutureDropSender(ty) => {
1673+
let type_index = self.payload_type_index(*ty)?;
1674+
let index = self.component.future_drop_sender(type_index);
1675+
return Ok((ExportKind::Func, index));
1676+
}
1677+
Import::FutureDropReceiver(ty) => {
1678+
let type_index = self.payload_type_index(*ty)?;
1679+
let index = self.component.future_drop_receiver(type_index);
1680+
return Ok((ExportKind::Func, index));
1681+
}
1682+
Import::StreamNew(info) => {
1683+
return Ok((
1684+
ExportKind::Func,
1685+
payload_indirect(self, info, PayloadFuncKind::StreamNew),
1686+
));
1687+
}
1688+
Import::StreamSend(info) => {
1689+
return Ok((
1690+
ExportKind::Func,
1691+
payload_indirect(self, info, PayloadFuncKind::StreamSend),
1692+
));
1693+
}
1694+
Import::StreamReceive(info) => {
1695+
return Ok((
1696+
ExportKind::Func,
1697+
payload_indirect(self, info, PayloadFuncKind::StreamReceive),
1698+
));
1699+
}
1700+
Import::StreamDropSender(ty) => {
1701+
let type_index = self.payload_type_index(*ty)?;
1702+
let index = self.component.stream_drop_sender(type_index);
1703+
return Ok((ExportKind::Func, index));
1704+
}
1705+
Import::StreamDropReceiver(ty) => {
1706+
let type_index = self.payload_type_index(*ty)?;
1707+
let index = self.component.stream_drop_receiver(type_index);
1708+
return Ok((ExportKind::Func, index));
1709+
}
15441710
Import::ExportedTaskStart(function) => {
15451711
let type_index = self
15461712
.root_import_type_encoder(None)
@@ -1786,10 +1952,7 @@ enum ShimKind<'a> {
17861952
},
17871953
PayloadFunc {
17881954
for_module: CustomModule<'a>,
1789-
module: &'a str,
1790-
imported: bool,
1791-
function: &'a str,
1792-
ordinal: usize,
1955+
info: &'a PayloadInfo,
17931956
kind: PayloadFuncKind,
17941957
},
17951958
TaskWait,
@@ -1829,6 +1992,27 @@ impl<'a> Shims<'a> {
18291992
let metadata = world.module_metadata_for(for_module);
18301993
let resolve = &world.encoder.metadata.resolve;
18311994

1995+
let payload_push = |me: &mut Self, module, info: &'a PayloadInfo, kind, params, results| {
1996+
let debug_name = format!("{module}-{}", info.name);
1997+
let name = me.shims.len().to_string();
1998+
me.push(Shim {
1999+
name,
2000+
debug_name,
2001+
options: RequiredOptions::empty(),
2002+
kind: ShimKind::PayloadFunc {
2003+
for_module,
2004+
info,
2005+
kind,
2006+
},
2007+
sig: WasmSignature {
2008+
params,
2009+
results,
2010+
indirect_params: false,
2011+
retptr: false,
2012+
},
2013+
});
2014+
};
2015+
18322016
for (module, field, import) in module_imports.imports() {
18332017
let (key, name, interface_key) = match import {
18342018
// These imports don't require shims, they can be satisfied
@@ -1842,18 +2026,78 @@ impl<'a> Shims<'a> {
18422026
| Import::ExportedResourceNew(..)
18432027
| Import::ErrorDrop
18442028
| Import::ExportedTaskStart(..)
1845-
| Import::ExportedTaskReturn(..) => continue,
1846-
1847-
Import::FutureNew(_) => todo!(),
1848-
Import::FutureSend(_) => todo!(),
1849-
Import::FutureReceive(_) => todo!(),
1850-
Import::FutureDropSender(_) => todo!(),
1851-
Import::FutureDropReceiver(_) => todo!(),
1852-
Import::StreamNew(_) => todo!(),
1853-
Import::StreamSend(_) => todo!(),
1854-
Import::StreamReceive(_) => todo!(),
1855-
Import::StreamDropSender(_) => todo!(),
1856-
Import::StreamDropReceiver(_) => todo!(),
2029+
| Import::ExportedTaskReturn(..)
2030+
| Import::FutureDropSender(..)
2031+
| Import::FutureDropReceiver(..)
2032+
| Import::StreamDropSender(..)
2033+
| Import::StreamDropReceiver(..) => continue,
2034+
2035+
Import::FutureNew(info) => {
2036+
payload_push(
2037+
self,
2038+
module,
2039+
info,
2040+
PayloadFuncKind::FutureNew,
2041+
vec![WasmType::I32],
2042+
Vec::new(),
2043+
);
2044+
continue;
2045+
}
2046+
Import::FutureSend(info) => {
2047+
payload_push(
2048+
self,
2049+
module,
2050+
info,
2051+
PayloadFuncKind::FutureSend,
2052+
vec![WasmType::I32; 3],
2053+
vec![WasmType::I32],
2054+
);
2055+
continue;
2056+
}
2057+
Import::FutureReceive(info) => {
2058+
payload_push(
2059+
self,
2060+
module,
2061+
info,
2062+
PayloadFuncKind::FutureReceive,
2063+
vec![WasmType::I32; 3],
2064+
vec![WasmType::I32],
2065+
);
2066+
continue;
2067+
}
2068+
Import::StreamNew(info) => {
2069+
payload_push(
2070+
self,
2071+
module,
2072+
info,
2073+
PayloadFuncKind::StreamNew,
2074+
vec![WasmType::I32],
2075+
Vec::new(),
2076+
);
2077+
continue;
2078+
}
2079+
Import::StreamSend(info) => {
2080+
payload_push(
2081+
self,
2082+
module,
2083+
info,
2084+
PayloadFuncKind::StreamSend,
2085+
vec![WasmType::I32; 3],
2086+
vec![WasmType::I32],
2087+
);
2088+
continue;
2089+
}
2090+
Import::StreamReceive(info) => {
2091+
payload_push(
2092+
self,
2093+
module,
2094+
info,
2095+
PayloadFuncKind::StreamReceive,
2096+
vec![WasmType::I32; 3],
2097+
vec![WasmType::I32],
2098+
);
2099+
continue;
2100+
}
18572101

18582102
Import::TaskWait => {
18592103
let name = self.shims.len().to_string();

0 commit comments

Comments
 (0)