@@ -10,20 +10,20 @@ use super::{
1010 ModuleType , RecordType , Remapping , ResourceId , TypeAlloc , TypeList , VariantCase ,
1111 } ,
1212} ;
13+ use crate :: collections:: index_map:: Entry ;
14+ use crate :: limits:: * ;
1315use crate :: prelude:: * ;
16+ use crate :: types:: {
17+ ComponentAnyTypeId , ComponentCoreModuleTypeId , ComponentCoreTypeId , ComponentDefinedType ,
18+ ComponentEntityType , Context , CoreInstanceTypeKind , LoweringInfo , Remap , SubtypeCx , TupleType ,
19+ TypeInfo , VariantType ,
20+ } ;
1421use crate :: validator:: names:: { ComponentName , ComponentNameKind , KebabStr , KebabString } ;
15- use crate :: { collections:: index_map:: Entry , CompositeInnerType } ;
1622use crate :: {
17- limits:: * ,
18- types:: {
19- ComponentAnyTypeId , ComponentCoreModuleTypeId , ComponentCoreTypeId , ComponentDefinedType ,
20- ComponentEntityType , Context , CoreInstanceTypeKind , LoweringInfo , Remap , SubtypeCx ,
21- TupleType , TypeInfo , VariantType ,
22- } ,
2323 BinaryReaderError , CanonicalOption , ComponentExportName , ComponentExternalKind ,
24- ComponentOuterAliasKind , ComponentTypeRef , CompositeType , ExternalKind , FuncType , GlobalType ,
25- InstantiationArgKind , MemoryType , RecGroup , Result , SubType , TableType , TypeBounds , ValType ,
26- WasmFeatures ,
24+ ComponentOuterAliasKind , ComponentTypeRef , CompositeInnerType , ExternalKind , FuncType ,
25+ GlobalType , InstantiationArgKind , MemoryType , PackedIndex , RefType , Result , SubType , TableType ,
26+ TypeBounds , ValType , WasmFeatures ,
2727} ;
2828use core:: mem;
2929
@@ -127,7 +127,7 @@ pub(crate) struct ComponentState {
127127 /// itself.
128128 ///
129129 /// The `Option<ValType>` in this mapping is whether or not the underlying
130- /// reprsentation of the resource is known to this component. Immediately
130+ /// representation of the resource is known to this component. Immediately
131131 /// defined resources, for example, will have `Some(I32)` here. Resources
132132 /// that come from transitively defined components, for example, will have
133133 /// `None`. In the type context all entries here are `None`.
@@ -1001,19 +1001,8 @@ impl ComponentState {
10011001
10021002 self . check_options ( None , & info, & options, types, offset) ?;
10031003
1004- let composite_type = CompositeType {
1005- inner : CompositeInnerType :: Func ( info. into_func_type ( ) ) ,
1006- shared : false ,
1007- } ;
1008- let lowered_ty = SubType {
1009- is_final : true ,
1010- supertype_idx : None ,
1011- composite_type,
1012- } ;
1013-
1014- let ( _is_new, group_id) =
1015- types. intern_canonical_rec_group ( RecGroup :: implicit ( offset, lowered_ty) ) ;
1016- let id = types[ group_id] . start ;
1004+ let lowered_ty = SubType :: func ( info. into_func_type ( ) , false ) ;
1005+ let id = types. intern_sub_type ( lowered_ty, offset) ;
10171006 self . core_funcs . push ( id) ;
10181007
10191008 Ok ( ( ) )
@@ -1026,18 +1015,9 @@ impl ComponentState {
10261015 offset : usize ,
10271016 ) -> Result < ( ) > {
10281017 let rep = self . check_local_resource ( resource, types, offset) ?;
1029- let composite_type = CompositeType {
1030- inner : CompositeInnerType :: Func ( FuncType :: new ( [ rep] , [ ValType :: I32 ] ) ) ,
1031- shared : false ,
1032- } ;
1033- let core_ty = SubType {
1034- is_final : true ,
1035- supertype_idx : None ,
1036- composite_type,
1037- } ;
1038- let ( _is_new, group_id) =
1039- types. intern_canonical_rec_group ( RecGroup :: implicit ( offset, core_ty) ) ;
1040- let id = types[ group_id] . start ;
1018+ let func_ty = FuncType :: new ( [ rep] , [ ValType :: I32 ] ) ;
1019+ let core_ty = SubType :: func ( func_ty, false ) ;
1020+ let id = types. intern_sub_type ( core_ty, offset) ;
10411021 self . core_funcs . push ( id) ;
10421022 Ok ( ( ) )
10431023 }
@@ -1049,18 +1029,9 @@ impl ComponentState {
10491029 offset : usize ,
10501030 ) -> Result < ( ) > {
10511031 self . resource_at ( resource, types, offset) ?;
1052- let composite_type = CompositeType {
1053- inner : CompositeInnerType :: Func ( FuncType :: new ( [ ValType :: I32 ] , [ ] ) ) ,
1054- shared : false ,
1055- } ;
1056- let core_ty = SubType {
1057- is_final : true ,
1058- supertype_idx : None ,
1059- composite_type,
1060- } ;
1061- let ( _is_new, group_id) =
1062- types. intern_canonical_rec_group ( RecGroup :: implicit ( offset, core_ty) ) ;
1063- let id = types[ group_id] . start ;
1032+ let func_ty = FuncType :: new ( [ ValType :: I32 ] , [ ] ) ;
1033+ let core_ty = SubType :: func ( func_ty, false ) ;
1034+ let id = types. intern_sub_type ( core_ty, offset) ;
10641035 self . core_funcs . push ( id) ;
10651036 Ok ( ( ) )
10661037 }
@@ -1072,18 +1043,9 @@ impl ComponentState {
10721043 offset : usize ,
10731044 ) -> Result < ( ) > {
10741045 let rep = self . check_local_resource ( resource, types, offset) ?;
1075- let composite_type = CompositeType {
1076- inner : CompositeInnerType :: Func ( FuncType :: new ( [ ValType :: I32 ] , [ rep] ) ) ,
1077- shared : false ,
1078- } ;
1079- let core_ty = SubType {
1080- is_final : true ,
1081- supertype_idx : None ,
1082- composite_type,
1083- } ;
1084- let ( _is_new, group_id) =
1085- types. intern_canonical_rec_group ( RecGroup :: implicit ( offset, core_ty) ) ;
1086- let id = types[ group_id] . start ;
1046+ let func_ty = FuncType :: new ( [ ValType :: I32 ] , [ rep] ) ;
1047+ let core_ty = SubType :: func ( func_ty, false ) ;
1048+ let id = types. intern_sub_type ( core_ty, offset) ;
10871049 self . core_funcs . push ( id) ;
10881050 Ok ( ( ) )
10891051 }
@@ -1112,6 +1074,78 @@ impl ComponentState {
11121074 bail ! ( offset, "type index {} is not a resource type" , idx)
11131075 }
11141076
1077+ pub fn thread_spawn (
1078+ & mut self ,
1079+ func_ty_index : u32 ,
1080+ types : & mut TypeAlloc ,
1081+ offset : usize ,
1082+ features : & WasmFeatures ,
1083+ ) -> Result < ( ) > {
1084+ if !features. shared_everything_threads ( ) {
1085+ bail ! (
1086+ offset,
1087+ "`thread.spawn` requires the shared-everything-threads proposal"
1088+ )
1089+ }
1090+
1091+ // Validate the type accepted by `thread.spawn`.
1092+ let core_type_id = match self . core_type_at ( func_ty_index, offset) ? {
1093+ ComponentCoreTypeId :: Sub ( c) => c,
1094+ ComponentCoreTypeId :: Module ( _) => bail ! ( offset, "expected a core function type" ) ,
1095+ } ;
1096+ let sub_ty = & types[ core_type_id] ;
1097+ if !sub_ty. composite_type . shared {
1098+ bail ! ( offset, "spawn type must be shared" ) ;
1099+ }
1100+ match & sub_ty. composite_type . inner {
1101+ CompositeInnerType :: Func ( func_ty) => {
1102+ if func_ty. params ( ) != [ ValType :: I32 ] {
1103+ bail ! (
1104+ offset,
1105+ "spawn function must take a single `i32` argument (currently)"
1106+ ) ;
1107+ }
1108+ if func_ty. results ( ) != [ ] {
1109+ bail ! ( offset, "spawn function must not return any values" ) ;
1110+ }
1111+ }
1112+ _ => bail ! ( offset, "spawn type must be a function" ) ,
1113+ }
1114+
1115+ // Insert the core function.
1116+ let packed_index = PackedIndex :: from_id ( core_type_id) . ok_or_else ( || {
1117+ format_err ! ( offset, "implementation limit: too many types in `TypeList`" )
1118+ } ) ?;
1119+ let start_func_ref = RefType :: concrete ( true , packed_index) ;
1120+ let func_ty = FuncType :: new ( [ ValType :: Ref ( start_func_ref) , ValType :: I32 ] , [ ValType :: I32 ] ) ;
1121+ let core_ty = SubType :: func ( func_ty, true ) ;
1122+ let id = types. intern_sub_type ( core_ty, offset) ;
1123+ self . core_funcs . push ( id) ;
1124+
1125+ Ok ( ( ) )
1126+ }
1127+
1128+ pub fn thread_hw_concurrency (
1129+ & mut self ,
1130+ types : & mut TypeAlloc ,
1131+ offset : usize ,
1132+ features : & WasmFeatures ,
1133+ ) -> Result < ( ) > {
1134+ if !features. shared_everything_threads ( ) {
1135+ bail ! (
1136+ offset,
1137+ "`thread.hw_concurrency` requires the shared-everything-threads proposal"
1138+ )
1139+ }
1140+
1141+ let func_ty = FuncType :: new ( [ ] , [ ValType :: I32 ] ) ;
1142+ let core_ty = SubType :: func ( func_ty, true ) ;
1143+ let id = types. intern_sub_type ( core_ty, offset) ;
1144+ self . core_funcs . push ( id) ;
1145+
1146+ Ok ( ( ) )
1147+ }
1148+
11151149 pub fn add_component ( & mut self , component : ComponentType , types : & mut TypeAlloc ) -> Result < ( ) > {
11161150 let id = types. push_ty ( component) ;
11171151 self . components . push ( id) ;
0 commit comments