@ -127,6 +127,9 @@ impl ValType {
/// The `externref` type, aka `(ref null extern)`.
/// The `externref` type, aka `(ref null extern)`.
pub const EXTERNREF : Self = ValType ::Ref ( RefType ::EXTERNREF ) ;
pub const EXTERNREF : Self = ValType ::Ref ( RefType ::EXTERNREF ) ;
/// The `nullexternref` type, aka `(ref null noextern)`.
pub const NULLEXTERNREF : Self = ValType ::Ref ( RefType ::NULLEXTERNREF ) ;
/// The `funcref` type, aka `(ref null func)`.
/// The `funcref` type, aka `(ref null func)`.
pub const FUNCREF : Self = ValType ::Ref ( RefType ::FUNCREF ) ;
pub const FUNCREF : Self = ValType ::Ref ( RefType ::FUNCREF ) ;
@ -139,6 +142,9 @@ impl ValType {
/// The `i31ref` type, aka `(ref null i31)`.
/// The `i31ref` type, aka `(ref null i31)`.
pub const I31REF : Self = ValType ::Ref ( RefType ::I31REF ) ;
pub const I31REF : Self = ValType ::Ref ( RefType ::I31REF ) ;
/// The `structref` type, aka `(ref null struct)`.
pub const STRUCTREF : Self = ValType ::Ref ( RefType ::STRUCTREF ) ;
/// The `nullref` type, aka `(ref null none)`.
/// The `nullref` type, aka `(ref null none)`.
pub const NULLREF : Self = ValType ::Ref ( RefType ::NULLREF ) ;
pub const NULLREF : Self = ValType ::Ref ( RefType ::NULLREF ) ;
@ -371,6 +377,12 @@ impl RefType {
heap_type : HeapType ::Extern ,
heap_type : HeapType ::Extern ,
} ;
} ;
/// The `nullexternref` type, aka `(ref null noextern)`.
pub const NULLEXTERNREF : Self = RefType {
is_nullable : true ,
heap_type : HeapType ::NoExtern ,
} ;
/// The `funcref` type, aka `(ref null func)`.
/// The `funcref` type, aka `(ref null func)`.
pub const FUNCREF : Self = RefType {
pub const FUNCREF : Self = RefType {
is_nullable : true ,
is_nullable : true ,
@ -395,6 +407,12 @@ impl RefType {
heap_type : HeapType ::I31 ,
heap_type : HeapType ::I31 ,
} ;
} ;
/// The `structref` type, aka `(ref null struct)`.
pub const STRUCTREF : Self = RefType {
is_nullable : true ,
heap_type : HeapType ::Struct ,
} ;
/// The `nullref` type, aka `(ref null none)`.
/// The `nullref` type, aka `(ref null none)`.
pub const NULLREF : Self = RefType {
pub const NULLREF : Self = RefType {
is_nullable : true ,
is_nullable : true ,
@ -752,7 +770,10 @@ impl HeapType {
/// Types that are not concrete, user-defined types are abstract types.
/// Types that are not concrete, user-defined types are abstract types.
#[ inline ]
#[ inline ]
pub fn is_concrete ( & self ) -> bool {
pub fn is_concrete ( & self ) -> bool {
matches ! ( self , HeapType ::ConcreteFunc ( _ ) | HeapType ::ConcreteArray ( _ ) )
matches ! (
self ,
HeapType ::ConcreteFunc ( _ ) | HeapType ::ConcreteArray ( _ ) | HeapType ::ConcreteStruct ( _ )
)
}
}
/// Is this a concrete, user-defined function type?
/// Is this a concrete, user-defined function type?
@ -797,6 +818,27 @@ impl HeapType {
self . as_concrete_array ( ) . unwrap ( )
self . as_concrete_array ( ) . unwrap ( )
}
}
/// Is this a concrete, user-defined struct type?
pub fn is_concrete_struct ( & self ) -> bool {
matches ! ( self , HeapType ::ConcreteStruct ( _ ) )
}
/// Get the underlying concrete, user-defined struct type, if any.
///
/// Returns `None` for if this is not a concrete struct type.
pub fn as_concrete_struct ( & self ) -> Option < & StructType > {
match self {
HeapType ::ConcreteStruct ( f ) = > Some ( f ) ,
_ = > None ,
}
}
/// Get the underlying concrete, user-defined type, panicking if this is not
/// a concrete struct type.
pub fn unwrap_concrete_struct ( & self ) -> & StructType {
self . as_concrete_struct ( ) . unwrap ( )
}
/// Get the top type of this heap type's type hierarchy.
/// Get the top type of this heap type's type hierarchy.
///
///
/// The returned heap type is a supertype of all types in this heap type's
/// The returned heap type is a supertype of all types in this heap type's
@ -1198,6 +1240,16 @@ pub enum StorageType {
ValType ( ValType ) ,
ValType ( ValType ) ,
}
}
impl fmt ::Display for StorageType {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
match self {
StorageType ::I8 = > write ! ( f , "i8" ) ,
StorageType ::I16 = > write ! ( f , "i16" ) ,
StorageType ::ValType ( ty ) = > fmt ::Display ::fmt ( ty , f ) ,
}
}
}
impl From < ValType > for StorageType {
impl From < ValType > for StorageType {
#[ inline ]
#[ inline ]
fn from ( v : ValType ) -> Self {
fn from ( v : ValType ) -> Self {
@ -1241,6 +1293,20 @@ impl StorageType {
self . as_val_type ( ) . unwrap ( )
self . as_val_type ( ) . unwrap ( )
}
}
/// Unpack this (possibly packed) storage type into a full `ValType`.
///
/// If this is a `StorageType::ValType`, then the inner `ValType` is
/// returned as-is.
///
/// If this is a packed `StorageType::I8` or `StorageType::I16, then a
/// `ValType::I32` is returned.
pub fn unpack ( & self ) -> & ValType {
match self {
StorageType ::I8 | StorageType ::I16 = > & ValType ::I32 ,
StorageType ::ValType ( ty ) = > ty ,
}
}
/// Does this field type match the other field type?
/// Does this field type match the other field type?
///
///
/// That is, is this field type a subtype of the other field type?
/// That is, is this field type a subtype of the other field type?
@ -1307,6 +1373,16 @@ pub struct FieldType {
element_type : StorageType ,
element_type : StorageType ,
}
}
impl fmt ::Display for FieldType {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
if self . mutability . is_var ( ) {
write ! ( f , "(mut {})" , self . element_type )
} else {
fmt ::Display ::fmt ( & self . element_type , f )
}
}
}
impl FieldType {
impl FieldType {
/// Construct a new field type from the given parts.
/// Construct a new field type from the given parts.
#[ inline ]
#[ inline ]
@ -1401,6 +1477,17 @@ pub struct StructType {
registered_type : RegisteredType ,
registered_type : RegisteredType ,
}
}
impl fmt ::Display for StructType {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
write ! ( f , "(struct" ) ? ;
for field in self . fields ( ) {
write ! ( f , " (field {field})" ) ? ;
}
write ! ( f , ")" ) ? ;
Ok ( ( ) )
}
}
impl StructType {
impl StructType {
/// Construct a new `StructType` with the given field types.
/// Construct a new `StructType` with the given field types.
///
///
@ -1576,15 +1663,19 @@ impl StructType {
}
}
pub ( crate ) fn comes_from_same_engine ( & self , engine : & Engine ) -> bool {
pub ( crate ) fn comes_from_same_engine ( & self , engine : & Engine ) -> bool {
Engine ::same ( self . registered_type . engine ( ) , engine )
Engine ::same ( self . registered_type ( ) . engine ( ) , engine )
}
}
pub ( crate ) fn type_index ( & self ) -> VMSharedTypeIndex {
pub ( crate ) fn type_index ( & self ) -> VMSharedTypeIndex {
self . registered_type . index ( )
self . registered_type ( ) . index ( )
}
}
pub ( crate ) fn as_wasm_struct_type ( & self ) -> & WasmStructType {
pub ( crate ) fn as_wasm_struct_type ( & self ) -> & WasmStructType {
self . registered_type . unwrap_struct ( )
self . registered_type ( ) . unwrap_struct ( )
}
pub ( crate ) fn registered_type ( & self ) -> & RegisteredType {
& self . registered_type
}
}
/// Construct a `StructType` from a `WasmStructType`.
/// Construct a `StructType` from a `WasmStructType`.
@ -1630,10 +1721,12 @@ impl StructType {
" VMSharedTypeIndex is not registered in the Engine ! Wrong \
" VMSharedTypeIndex is not registered in the Engine ! Wrong \
engine ? Didn 't root the index somewhere ? " ,
engine ? Didn 't root the index somewhere ? " ,
) ;
) ;
assert ! ( ty . is_struct ( ) ) ;
Self ::from_registered_type ( ty )
Self {
}
registered_type : ty ,
}
pub ( crate ) fn from_registered_type ( registered_type : RegisteredType ) -> Self {
debug_assert ! ( registered_type . is_struct ( ) ) ;
Self { registered_type }
}
}
}
}
@ -1860,10 +1953,12 @@ impl ArrayType {
" VMSharedTypeIndex is not registered in the Engine ! Wrong \
" VMSharedTypeIndex is not registered in the Engine ! Wrong \
engine ? Didn 't root the index somewhere ? " ,
engine ? Didn 't root the index somewhere ? " ,
) ;
) ;
assert ! ( ty . is_array ( ) ) ;
Self ::from_registered_type ( ty )
Self {
}
registered_type : ty ,
}
pub ( crate ) fn from_registered_type ( registered_type : RegisteredType ) -> Self {
debug_assert ! ( registered_type . is_array ( ) ) ;
Self { registered_type }
}
}
}
}
@ -2214,10 +2309,12 @@ impl FuncType {
" VMSharedTypeIndex is not registered in the Engine ! Wrong \
" VMSharedTypeIndex is not registered in the Engine ! Wrong \
engine ? Didn 't root the index somewhere ? " ,
engine ? Didn 't root the index somewhere ? " ,
) ;
) ;
assert ! ( ty . is_func ( ) ) ;
Self ::from_registered_type ( ty )
Self {
}
registered_type : ty ,
}
pub ( crate ) fn from_registered_type ( registered_type : RegisteredType ) -> Self {
debug_assert ! ( registered_type . is_func ( ) ) ;
Self { registered_type }
}
}
}
}