Skip to content

Commit d82b009

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

File tree

2 files changed

+400
-76
lines changed

2 files changed

+400
-76
lines changed

crates/wit-component/src/encoding.rs

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

12831381
ShimKind::TaskWait => self.component.task_wait(self.memory_index.unwrap()),
@@ -1294,6 +1392,17 @@ impl<'a> EncodingState<'a> {
12941392
Ok(())
12951393
}
12961394

1395+
fn payload_type_index(&mut self, ty: TypeId) -> Result<u32> {
1396+
let resolve = &self.info.encoder.metadata.resolve;
1397+
let ComponentValType::Type(type_index) = self
1398+
.root_import_type_encoder(None)
1399+
.encode_valtype(resolve, &Type::Id(ty))?
1400+
else {
1401+
unreachable!()
1402+
};
1403+
Ok(type_index)
1404+
}
1405+
12971406
/// This is a helper function that will declare, in the component itself,
12981407
/// all exported resources.
12991408
///
@@ -1439,6 +1548,19 @@ impl<'a> EncodingState<'a> {
14391548
) -> Result<(ExportKind, u32)> {
14401549
log::trace!("attempting to materialize import of `{module}::{field}` for {for_module:?}");
14411550
let resolve = &self.info.encoder.metadata.resolve;
1551+
let payload_indirect = |me: &mut Self, info, kind| {
1552+
me.component.core_alias_export(
1553+
me.shim_instance_index.expect("shim should be instantiated"),
1554+
&shims.shims[&ShimKind::PayloadFunc {
1555+
for_module,
1556+
module,
1557+
info,
1558+
kind,
1559+
}]
1560+
.name,
1561+
ExportKind::Func,
1562+
)
1563+
};
14421564
let name_tmp;
14431565
let (key, name, interface_key, abi) = match import {
14441566
// Main module dependencies on an adapter in use are done with an
@@ -1531,16 +1653,62 @@ impl<'a> EncodingState<'a> {
15311653
);
15321654
return Ok((ExportKind::Func, index));
15331655
}
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!(),
1656+
Import::FutureNew(info) => {
1657+
return Ok((
1658+
ExportKind::Func,
1659+
payload_indirect(self, info, PayloadFuncKind::FutureNew),
1660+
));
1661+
}
1662+
Import::FutureSend(info) => {
1663+
return Ok((
1664+
ExportKind::Func,
1665+
payload_indirect(self, info, PayloadFuncKind::FutureSend),
1666+
));
1667+
}
1668+
Import::FutureReceive(info) => {
1669+
return Ok((
1670+
ExportKind::Func,
1671+
payload_indirect(self, info, PayloadFuncKind::FutureReceive),
1672+
));
1673+
}
1674+
Import::FutureDropSender(ty) => {
1675+
let type_index = self.payload_type_index(*ty)?;
1676+
let index = self.component.future_drop_sender(type_index);
1677+
return Ok((ExportKind::Func, index));
1678+
}
1679+
Import::FutureDropReceiver(ty) => {
1680+
let type_index = self.payload_type_index(*ty)?;
1681+
let index = self.component.future_drop_receiver(type_index);
1682+
return Ok((ExportKind::Func, index));
1683+
}
1684+
Import::StreamNew(info) => {
1685+
return Ok((
1686+
ExportKind::Func,
1687+
payload_indirect(self, info, PayloadFuncKind::StreamNew),
1688+
));
1689+
}
1690+
Import::StreamSend(info) => {
1691+
return Ok((
1692+
ExportKind::Func,
1693+
payload_indirect(self, info, PayloadFuncKind::StreamSend),
1694+
));
1695+
}
1696+
Import::StreamReceive(info) => {
1697+
return Ok((
1698+
ExportKind::Func,
1699+
payload_indirect(self, info, PayloadFuncKind::StreamReceive),
1700+
));
1701+
}
1702+
Import::StreamDropSender(ty) => {
1703+
let type_index = self.payload_type_index(*ty)?;
1704+
let index = self.component.stream_drop_sender(type_index);
1705+
return Ok((ExportKind::Func, index));
1706+
}
1707+
Import::StreamDropReceiver(ty) => {
1708+
let type_index = self.payload_type_index(*ty)?;
1709+
let index = self.component.stream_drop_receiver(type_index);
1710+
return Ok((ExportKind::Func, index));
1711+
}
15441712
Import::ExportedTaskStart(function) => {
15451713
let type_index = self
15461714
.root_import_type_encoder(None)
@@ -1787,9 +1955,7 @@ enum ShimKind<'a> {
17871955
PayloadFunc {
17881956
for_module: CustomModule<'a>,
17891957
module: &'a str,
1790-
imported: bool,
1791-
function: &'a str,
1792-
ordinal: usize,
1958+
info: &'a PayloadInfo,
17931959
kind: PayloadFuncKind,
17941960
},
17951961
TaskWait,
@@ -1829,6 +1995,28 @@ impl<'a> Shims<'a> {
18291995
let metadata = world.module_metadata_for(for_module);
18301996
let resolve = &world.encoder.metadata.resolve;
18311997

1998+
let payload_push = |me: &mut Self, module, info: &'a PayloadInfo, kind, params, results| {
1999+
let debug_name = format!("{module}-{}", info.name);
2000+
let name = me.shims.len().to_string();
2001+
me.push(Shim {
2002+
name,
2003+
debug_name,
2004+
options: RequiredOptions::empty(),
2005+
kind: ShimKind::PayloadFunc {
2006+
for_module,
2007+
module,
2008+
info,
2009+
kind,
2010+
},
2011+
sig: WasmSignature {
2012+
params,
2013+
results,
2014+
indirect_params: false,
2015+
retptr: false,
2016+
},
2017+
});
2018+
};
2019+
18322020
for (module, field, import) in module_imports.imports() {
18332021
let (key, name, interface_key) = match import {
18342022
// These imports don't require shims, they can be satisfied
@@ -1842,18 +2030,78 @@ impl<'a> Shims<'a> {
18422030
| Import::ExportedResourceNew(..)
18432031
| Import::ErrorDrop
18442032
| 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!(),
2033+
| Import::ExportedTaskReturn(..)
2034+
| Import::FutureDropSender(..)
2035+
| Import::FutureDropReceiver(..)
2036+
| Import::StreamDropSender(..)
2037+
| Import::StreamDropReceiver(..) => continue,
2038+
2039+
Import::FutureNew(info) => {
2040+
payload_push(
2041+
self,
2042+
module,
2043+
info,
2044+
PayloadFuncKind::FutureNew,
2045+
vec![WasmType::I32],
2046+
Vec::new(),
2047+
);
2048+
continue;
2049+
}
2050+
Import::FutureSend(info) => {
2051+
payload_push(
2052+
self,
2053+
module,
2054+
info,
2055+
PayloadFuncKind::FutureSend,
2056+
vec![WasmType::I32; 3],
2057+
vec![WasmType::I32],
2058+
);
2059+
continue;
2060+
}
2061+
Import::FutureReceive(info) => {
2062+
payload_push(
2063+
self,
2064+
module,
2065+
info,
2066+
PayloadFuncKind::FutureReceive,
2067+
vec![WasmType::I32; 3],
2068+
vec![WasmType::I32],
2069+
);
2070+
continue;
2071+
}
2072+
Import::StreamNew(info) => {
2073+
payload_push(
2074+
self,
2075+
module,
2076+
info,
2077+
PayloadFuncKind::StreamNew,
2078+
vec![WasmType::I32],
2079+
Vec::new(),
2080+
);
2081+
continue;
2082+
}
2083+
Import::StreamSend(info) => {
2084+
payload_push(
2085+
self,
2086+
module,
2087+
info,
2088+
PayloadFuncKind::StreamSend,
2089+
vec![WasmType::I32; 3],
2090+
vec![WasmType::I32],
2091+
);
2092+
continue;
2093+
}
2094+
Import::StreamReceive(info) => {
2095+
payload_push(
2096+
self,
2097+
module,
2098+
info,
2099+
PayloadFuncKind::StreamReceive,
2100+
vec![WasmType::I32; 3],
2101+
vec![WasmType::I32],
2102+
);
2103+
continue;
2104+
}
18572105

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

0 commit comments

Comments
 (0)