7272//! component model.
7373
7474use crate :: metadata:: { self , Bindgen , ModuleMetadata } ;
75- use crate :: validation:: { Export , ExportMap , Import , ImportInstance , ImportMap } ;
75+ use crate :: validation:: { Export , ExportMap , Import , ImportInstance , ImportMap , PayloadInfo } ;
7676use crate :: StringEncoding ;
7777use anyhow:: { anyhow, bail, Context , Result } ;
7878use indexmap:: { IndexMap , IndexSet } ;
@@ -84,8 +84,8 @@ use wasm_encoder::*;
8484use wasmparser:: Validator ;
8585use 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
9191const 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