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" ;
@@ -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