@@ -6,17 +6,16 @@ use std::sync::Arc;
66
77use crate :: compiler:: ModuleCode ;
88use crate :: component:: binary_grammar:: {
9- ComponentDefinedKind , ComponentFuncResult , ComponentTypeDef , ComponentValueKind ,
10- PrimitiveValueKind ,
9+ ComponentDefinedKind , ComponentTypeDef , ComponentValueKind , PrimitiveValueKind ,
1110} ;
1211use crate :: component:: flatten:: Initializer ;
1312use crate :: error:: { Error , Result } ;
1413#[ cfg( feature = "jit" ) ]
1514use crate :: jit:: assembler:: JitFunction ;
1615use crate :: {
17- compiler, ensure, instantiation_err, trap, AddrType , Component , ComponentFuncKind ,
18- ComponentInstance , ComponentValue , DataMode , ElementMode , ImportDescription ,
19- InstantiatedComponent , Instruction , LiftedFunc , Module , Mutability , Trap ,
16+ compiler, ensure, instantiation_err, trap, AddrType , Component , ComponentInstance ,
17+ ComponentValue , DataMode , ElementMode , ImportDescription , InstantiatedComponent , Instruction ,
18+ LiftedFunc , Module , Mutability , Trap ,
2019} ;
2120
2221use crate :: binary_grammar:: {
@@ -1246,6 +1245,103 @@ impl Store {
12461245 self . lower_value ( value, None , types, lifted, flat) ?;
12471246 }
12481247 }
1248+ ComponentValue :: Variant ( case_name, payload) => {
1249+ let defined = resolve_defined_type ( param_ty, types) ;
1250+ let cases = match defined {
1251+ Some ( ComponentDefinedKind :: Variant ( cases) ) => cases,
1252+ _ => instantiation_err ! ( "variant lower requires variant type" ) ,
1253+ } ;
1254+
1255+ let Some ( case_i) = cases. iter ( ) . position ( |c| c. name == case_name) else {
1256+ instantiation_err ! ( "enum case not found: {case_name}" )
1257+ } ;
1258+
1259+ let max_payload = cases
1260+ . iter ( )
1261+ . map ( |c| c. ty . as_ref ( ) . map_or ( 0 , |ty| ty. flat_count ( types) ) )
1262+ . max ( )
1263+ . unwrap_or ( 0 ) ;
1264+
1265+ flat. push ( RawValue :: from ( case_i as i32 ) ) ;
1266+
1267+ let before = flat. len ( ) ;
1268+ if let Some ( value) = payload {
1269+ self . lower_value ( * value, None , types, lifted, flat) ?;
1270+ }
1271+
1272+ let written = flat. len ( ) - before - 1 ;
1273+ let padding = max_payload - written;
1274+ flat. extend ( std:: iter:: repeat_n ( RawValue :: from ( i32:: MAX ) , padding) ) ;
1275+ }
1276+ ComponentValue :: Enum ( case_name) => {
1277+ let defined = resolve_defined_type ( param_ty, types) ;
1278+
1279+ let cases = match defined {
1280+ Some ( ComponentDefinedKind :: Enum ( cases) ) => cases,
1281+ _ => instantiation_err ! ( "enum lower requires enum type" ) ,
1282+ } ;
1283+
1284+ let Some ( case_i) = cases. iter ( ) . position ( |c| * c == case_name) else {
1285+ instantiation_err ! ( "enum case not found: {case_name}" )
1286+ } ;
1287+
1288+ flat. push ( RawValue :: from ( case_i as i32 ) ) ;
1289+ }
1290+ ComponentValue :: Option ( opt) => {
1291+ let defined = resolve_defined_type ( param_ty, types) ;
1292+
1293+ let inner_ty = match defined {
1294+ Some ( ComponentDefinedKind :: Option ( ty) ) => ty,
1295+ _ => instantiation_err ! ( "option lower requires option type" ) ,
1296+ } ;
1297+
1298+ let payload_count = inner_ty. flat_count ( types) ;
1299+
1300+ match opt {
1301+ None => flat. extend ( std:: iter:: repeat_n (
1302+ RawValue :: from ( i32:: MAX ) ,
1303+ payload_count + 1 ,
1304+ ) ) ,
1305+ Some ( value) => {
1306+ flat. push ( RawValue :: from ( 1i32 ) ) ;
1307+ self . lower_value ( * value, None , types, lifted, flat) ?;
1308+ }
1309+ }
1310+ }
1311+ ComponentValue :: Result ( result) => {
1312+ let defined = resolve_defined_type ( param_ty, types) ;
1313+ let ( ok_ty, err_ty) = match defined {
1314+ Some ( ComponentDefinedKind :: Result { ok, err } ) => ( ok, err) ,
1315+ _ => instantiation_err ! ( "result lower requires result type" ) ,
1316+ } ;
1317+
1318+ let ok_count = ok_ty. as_ref ( ) . map_or ( 0 , |ty| ty. flat_count ( types) ) ;
1319+ let err_count = err_ty. as_ref ( ) . map_or ( 0 , |ty| ty. flat_count ( types) ) ;
1320+ let max_payload = ok_count. max ( err_count) ;
1321+
1322+ let before = flat. len ( ) ;
1323+
1324+ match result {
1325+ Ok ( value) => {
1326+ flat. push ( RawValue :: from ( 0i32 ) ) ;
1327+
1328+ if let Some ( value) = value {
1329+ self . lower_value ( * value, None , types, lifted, flat) ?;
1330+ }
1331+ }
1332+ Err ( value) => {
1333+ flat. push ( RawValue :: from ( 1i32 ) ) ;
1334+
1335+ if let Some ( value) = value {
1336+ self . lower_value ( * value, None , types, lifted, flat) ?;
1337+ }
1338+ }
1339+ }
1340+
1341+ let written = flat. len ( ) - before - 1 ;
1342+ let padding = max_payload - written;
1343+ flat. extend ( std:: iter:: repeat_n ( RawValue :: from ( i32:: MAX ) , padding) ) ;
1344+ }
12491345 _ => todo ! ( "lower {:?}" , value) ,
12501346 }
12511347 Ok ( ( ) )
@@ -1279,6 +1375,7 @@ impl Store {
12791375 ComponentValueKind :: Primitive ( p) => {
12801376 let val = flat[ * cursor] ;
12811377 * cursor += 1 ;
1378+
12821379 Ok ( match p {
12831380 PrimitiveValueKind :: Bool => ComponentValue :: Bool ( val. as_i32 ( ) != 0 ) ,
12841381 PrimitiveValueKind :: S8 => ComponentValue :: S8 ( val. as_i32 ( ) as i8 ) ,
@@ -1387,6 +1484,88 @@ impl Store {
13871484
13881485 Ok ( ComponentValue :: Tuple ( values) )
13891486 }
1487+ ComponentTypeDef :: Defined ( ComponentDefinedKind :: Variant ( cases) ) => {
1488+ let discriminant = flat[ * cursor] . as_i32 ( ) as usize ;
1489+ * cursor += 1 ;
1490+
1491+ let max_payload = cases
1492+ . iter ( )
1493+ . map ( |c| c. ty . as_ref ( ) . map_or ( 0 , |ty| ty. flat_count ( types) ) )
1494+ . max ( )
1495+ . unwrap_or ( 0 ) ;
1496+
1497+ let case = & cases[ discriminant] ;
1498+ let payload = if let Some ( ty) = & case. ty {
1499+ let val = self . lift_value ( ty, flat, cursor, lifted, types) ?;
1500+ let this_count = ty. flat_count ( types) ;
1501+
1502+ * cursor += max_payload - this_count;
1503+
1504+ Some ( Box :: new ( val) )
1505+ } else {
1506+ * cursor += max_payload;
1507+
1508+ None
1509+ } ;
1510+
1511+ Ok ( ComponentValue :: Variant ( case. name . clone ( ) , payload) )
1512+ }
1513+ ComponentTypeDef :: Defined ( ComponentDefinedKind :: Enum ( cases) ) => {
1514+ let discriminant = flat[ * cursor] . as_i32 ( ) as usize ;
1515+ * cursor += 1 ;
1516+
1517+ Ok ( ComponentValue :: Enum ( cases[ discriminant] . clone ( ) ) )
1518+ }
1519+ ComponentTypeDef :: Defined ( ComponentDefinedKind :: Option ( inner_ty) ) => {
1520+ let discriminant = flat[ * cursor] . as_i32 ( ) ;
1521+ * cursor += 1 ;
1522+
1523+ let payload_count = inner_ty. flat_count ( types) ;
1524+ if discriminant == 0 {
1525+ * cursor += payload_count;
1526+
1527+ return Ok ( ComponentValue :: Option ( None ) ) ;
1528+ }
1529+
1530+ let val = self . lift_value ( inner_ty, flat, cursor, lifted, types) ?;
1531+
1532+ Ok ( ComponentValue :: Option ( Some ( Box :: new ( val) ) ) )
1533+ }
1534+ ComponentTypeDef :: Defined ( ComponentDefinedKind :: Result { ok, err } ) => {
1535+ let discriminant = flat[ * cursor] . as_i32 ( ) ;
1536+ * cursor += 1 ;
1537+
1538+ let ok_count = ok. as_ref ( ) . map_or ( 0 , |ty| ty. flat_count ( types) ) ;
1539+ let err_count = err. as_ref ( ) . map_or ( 0 , |ty| ty. flat_count ( types) ) ;
1540+ let max_payload = ok_count. max ( err_count) ;
1541+
1542+ if discriminant == 0 {
1543+ let val = if let Some ( ty) = ok {
1544+ let v = self . lift_value ( ty, flat, cursor, lifted, types) ?;
1545+ * cursor += max_payload - ok_count;
1546+
1547+ Some ( Box :: new ( v) )
1548+ } else {
1549+ * cursor += max_payload;
1550+
1551+ None
1552+ } ;
1553+ return Ok ( ComponentValue :: Result ( Ok ( val) ) ) ;
1554+ }
1555+
1556+ let val = if let Some ( ty) = err {
1557+ let v = self . lift_value ( ty, flat, cursor, lifted, types) ?;
1558+ * cursor += max_payload - err_count;
1559+
1560+ Some ( Box :: new ( v) )
1561+ } else {
1562+ * cursor += max_payload;
1563+
1564+ None
1565+ } ;
1566+
1567+ Ok ( ComponentValue :: Result ( Err ( val) ) )
1568+ }
13901569 other => todo ! ( "lift type {:?}" , other) ,
13911570 } ,
13921571 }
@@ -3185,6 +3364,19 @@ const fn limits_match(actual: &Limit, expected: &Limit) -> bool {
31853364 actual. min >= expected. min && ( expected. max == u64:: MAX || actual. max <= expected. max )
31863365}
31873366
3367+ fn resolve_defined_type < ' a > (
3368+ param_ty : Option < & ComponentValueKind > ,
3369+ types : & ' a [ ComponentTypeDef ] ,
3370+ ) -> Option < & ' a ComponentDefinedKind > {
3371+ match param_ty? {
3372+ ComponentValueKind :: Type ( i) => match & types[ * i as usize ] {
3373+ ComponentTypeDef :: Defined ( d) => Some ( d) ,
3374+ _ => None ,
3375+ } ,
3376+ _ => None ,
3377+ }
3378+ }
3379+
31883380fn component_value_byte_size ( v : & ComponentValue ) -> usize {
31893381 match v {
31903382 ComponentValue :: Bool ( _) | ComponentValue :: S8 ( _) | ComponentValue :: U8 ( _) => 1 ,
0 commit comments