Browse Source

A handful of little tweaks for GC types (#8925)

* A handful of little tweaks for GC types

Splitting this out from a larger PR so that it is easier to review and
everything can land quicker.

* Don't use `Cow`, just use references
pull/8926/head
Nick Fitzgerald 4 months ago
committed by GitHub
parent
commit
34f71bec29
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 129
      crates/wasmtime/src/runtime/types.rs

129
crates/wasmtime/src/runtime/types.rs

@ -127,6 +127,9 @@ impl ValType {
/// The `externref` type, aka `(ref null extern)`.
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)`.
pub const FUNCREF: Self = ValType::Ref(RefType::FUNCREF);
@ -139,6 +142,9 @@ impl ValType {
/// The `i31ref` type, aka `(ref null i31)`.
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)`.
pub const NULLREF: Self = ValType::Ref(RefType::NULLREF);
@ -371,6 +377,12 @@ impl RefType {
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)`.
pub const FUNCREF: Self = RefType {
is_nullable: true,
@ -395,6 +407,12 @@ impl RefType {
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)`.
pub const NULLREF: Self = RefType {
is_nullable: true,
@ -752,7 +770,10 @@ impl HeapType {
/// Types that are not concrete, user-defined types are abstract types.
#[inline]
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?
@ -797,6 +818,27 @@ impl HeapType {
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.
///
/// The returned heap type is a supertype of all types in this heap type's
@ -1198,6 +1240,16 @@ pub enum StorageType {
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 {
#[inline]
fn from(v: ValType) -> Self {
@ -1241,6 +1293,20 @@ impl StorageType {
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?
///
/// That is, is this field type a subtype of the other field type?
@ -1307,6 +1373,16 @@ pub struct FieldType {
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 {
/// Construct a new field type from the given parts.
#[inline]
@ -1401,6 +1477,17 @@ pub struct StructType {
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 {
/// 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 {
Engine::same(self.registered_type.engine(), engine)
Engine::same(self.registered_type().engine(), engine)
}
pub(crate) fn type_index(&self) -> VMSharedTypeIndex {
self.registered_type.index()
self.registered_type().index()
}
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`.
@ -1630,10 +1721,12 @@ impl StructType {
"VMSharedTypeIndex is not registered in the Engine! Wrong \
engine? Didn't root the index somewhere?",
);
assert!(ty.is_struct());
Self {
registered_type: ty,
}
Self::from_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 \
engine? Didn't root the index somewhere?",
);
assert!(ty.is_array());
Self {
registered_type: ty,
}
Self::from_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 \
engine? Didn't root the index somewhere?",
);
assert!(ty.is_func());
Self {
registered_type: ty,
}
Self::from_registered_type(ty)
}
pub(crate) fn from_registered_type(registered_type: RegisteredType) -> Self {
debug_assert!(registered_type.is_func());
Self { registered_type }
}
}

Loading…
Cancel
Save