From 38845a026d9d0f90069bbc1d9f7dea63d536ca23 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 1 Nov 2024 17:39:51 -0700 Subject: [PATCH] threads: add `WasmCompositeInnerType` layer (#9520) * threads: add `WasmCompositeInnerType` layer As in `wasm-tools`, push the type down a layer so that `WasmCompositeType` can be marked shared. This leaves several holes to be filled in by future commits (all marked with `TODO: handle shared`); in effect, this change allows `WasmCompositeType` to be marked shared but mostly does not wire up the sharedness during translation. * review: remove TODOs * review: remove more TODOs * review: refactor to use `GcTypeLayouts::gc_layout` * review: propagate sharedness * review: fail if an unwrapped type is shared * review: propagate sharedness more * review: redefine accessors as unshared * fix: add `DisabledLayouts` to satisfy `GcRuntime::layouts()` * review: panic on shared * review: remove unnecessary assert --- crates/cranelift/src/func_environ.rs | 6 +- crates/cranelift/src/gc/enabled.rs | 64 ++++------- crates/environ/src/compile/module_types.rs | 73 ++++++++++--- crates/environ/src/gc.rs | 14 ++- crates/environ/src/types.rs | 106 +++++++++++++------ crates/wasmtime/src/runtime/type_registry.rs | 18 ++-- crates/wasmtime/src/runtime/types.rs | 22 +++- crates/wasmtime/src/runtime/vm/const_expr.rs | 14 ++- 8 files changed, 205 insertions(+), 112 deletions(-) diff --git a/crates/cranelift/src/func_environ.rs b/crates/cranelift/src/func_environ.rs index d0713b70463d..4fa5599ba537 100644 --- a/crates/cranelift/src/func_environ.rs +++ b/crates/cranelift/src/func_environ.rs @@ -22,7 +22,7 @@ use wasmtime_environ::{ BuiltinFunctionIndex, DataIndex, ElemIndex, EngineOrModuleTypeIndex, FuncIndex, GlobalIndex, IndexType, Memory, MemoryIndex, MemoryStyle, Module, ModuleInternedTypeIndex, ModuleTranslation, ModuleTypesBuilder, PtrSize, Table, TableIndex, Tunables, TypeConvert, - TypeIndex, VMOffsets, WasmCompositeType, WasmFuncType, WasmHeapTopType, WasmHeapType, + TypeIndex, VMOffsets, WasmCompositeInnerType, WasmFuncType, WasmHeapTopType, WasmHeapType, WasmRefType, WasmResult, WasmValType, }; use wasmtime_environ::{FUNCREF_INIT_BIT, FUNCREF_MASK}; @@ -1911,8 +1911,8 @@ impl<'module_environment> crate::translate::FuncEnvironment fn struct_fields_len(&mut self, struct_type_index: TypeIndex) -> WasmResult { let ty = self.module.types[struct_type_index]; - match &self.types[ty].composite_type { - WasmCompositeType::Struct(s) => Ok(s.fields.len()), + match &self.types[ty].composite_type.inner { + WasmCompositeInnerType::Struct(s) => Ok(s.fields.len()), _ => unreachable!(), } } diff --git a/crates/cranelift/src/gc/enabled.rs b/crates/cranelift/src/gc/enabled.rs index 1ab369cf0eeb..8fc9a171c79a 100644 --- a/crates/cranelift/src/gc/enabled.rs +++ b/crates/cranelift/src/gc/enabled.rs @@ -12,8 +12,8 @@ use cranelift_frontend::FunctionBuilder; use smallvec::SmallVec; use wasmtime_environ::{ wasm_unsupported, Collector, GcArrayLayout, GcLayout, GcStructLayout, ModuleInternedTypeIndex, - PtrSize, TypeIndex, VMGcKind, WasmCompositeType, WasmHeapTopType, WasmHeapType, WasmRefType, - WasmResult, WasmStorageType, WasmValType, I31_DISCRIMINANT, NON_NULL_NON_I31_MASK, + PtrSize, TypeIndex, VMGcKind, WasmHeapTopType, WasmHeapType, WasmRefType, WasmResult, + WasmStorageType, WasmValType, I31_DISCRIMINANT, NON_NULL_NON_I31_MASK, }; #[cfg(feature = "gc-drc")] @@ -285,10 +285,7 @@ pub fn translate_struct_new_default( struct_type_index: TypeIndex, ) -> WasmResult { let interned_ty = func_env.module.types[struct_type_index]; - let struct_ty = match &func_env.types[interned_ty].composite_type { - WasmCompositeType::Struct(s) => s, - _ => unreachable!(), - }; + let struct_ty = func_env.types.unwrap_struct(interned_ty)?; let fields = struct_ty .fields .iter() @@ -317,12 +314,7 @@ pub fn translate_struct_get( let struct_size_val = builder.ins().iconst(ir::types::I32, i64::from(struct_size)); let field_offset = struct_layout.fields[field_index]; - - let field_ty = match &func_env.types[interned_type_index].composite_type { - WasmCompositeType::Struct(s) => &s.fields[field_index], - _ => unreachable!(), - }; - + let field_ty = &func_env.types.unwrap_struct(interned_type_index)?.fields[field_index]; let field_size = wasmtime_environ::byte_size_of_wasm_ty_in_gc_heap(&field_ty.element_type); assert!(field_offset + field_size <= struct_size); @@ -355,12 +347,7 @@ fn translate_struct_get_and_extend( let struct_size_val = builder.ins().iconst(ir::types::I32, i64::from(struct_size)); let field_offset = struct_layout.fields[field_index]; - - let field_ty = match &func_env.types[interned_type_index].composite_type { - WasmCompositeType::Struct(s) => &s.fields[field_index], - _ => unreachable!(), - }; - + let field_ty = &func_env.types.unwrap_struct(interned_type_index)?.fields[field_index]; let field_size = wasmtime_environ::byte_size_of_wasm_ty_in_gc_heap(&field_ty.element_type); assert!(field_offset + field_size <= struct_size); @@ -433,12 +420,7 @@ pub fn translate_struct_set( let struct_size_val = builder.ins().iconst(ir::types::I32, i64::from(struct_size)); let field_offset = struct_layout.fields[field_index]; - - let field_ty = match &func_env.types[interned_type_index].composite_type { - WasmCompositeType::Struct(s) => &s.fields[field_index], - _ => unreachable!(), - }; - + let field_ty = &func_env.types.unwrap_struct(interned_type_index)?.fields[field_index]; let field_size = wasmtime_environ::byte_size_of_wasm_ty_in_gc_heap(&field_ty.element_type); assert!(field_offset + field_size <= struct_size); @@ -480,9 +462,7 @@ pub fn translate_array_new_default( len: ir::Value, ) -> WasmResult { let interned_ty = func_env.module.types[array_type_index]; - let WasmCompositeType::Array(array_ty) = &func_env.types[interned_ty].composite_type else { - unreachable!() - }; + let array_ty = func_env.types.unwrap_array(interned_ty)?; let elem = default_value(&mut builder.cursor(), func_env, &array_ty.0.element_type); gc_compiler(func_env)?.alloc_array( func_env, @@ -532,8 +512,10 @@ impl ArrayInit<'_> { ir::Value, ) -> WasmResult<()>, ) -> WasmResult<()> { + assert!(!func_env.types[interned_type_index].composite_type.shared); let array_ty = func_env.types[interned_type_index] .composite_type + .inner .unwrap_array(); let elem_ty = array_ty.0.element_type; let elem_size = wasmtime_environ::byte_size_of_wasm_ty_in_gc_heap(&elem_ty); @@ -698,9 +680,9 @@ pub fn translate_array_fill( one_elem_size, fill_end, |func_env, builder, elem_addr| { - let elem_ty = func_env.types[interned_type_index] - .composite_type - .unwrap_array() + let elem_ty = func_env + .types + .unwrap_array(interned_type_index)? .0 .element_type; write_field_at_addr(func_env, builder, elem_ty, elem_addr, value) @@ -865,9 +847,7 @@ pub fn translate_array_get( let array_type_index = func_env.module.types[array_type_index]; let elem_addr = array_elem_addr(func_env, builder, array_type_index, array_ref, index); - let array_ty = func_env.types[array_type_index] - .composite_type - .unwrap_array(); + let array_ty = func_env.types.unwrap_array(array_type_index)?; let elem_ty = array_ty.0.element_type; read_field_at_addr(func_env, builder, elem_ty, elem_addr, None) @@ -883,9 +863,7 @@ pub fn translate_array_get_s( let array_type_index = func_env.module.types[array_type_index]; let elem_addr = array_elem_addr(func_env, builder, array_type_index, array_ref, index); - let array_ty = func_env.types[array_type_index] - .composite_type - .unwrap_array(); + let array_ty = func_env.types.unwrap_array(array_type_index)?; let elem_ty = array_ty.0.element_type; read_field_at_addr(func_env, builder, elem_ty, elem_addr, Some(Extension::Sign)) @@ -901,9 +879,7 @@ pub fn translate_array_get_u( let array_type_index = func_env.module.types[array_type_index]; let elem_addr = array_elem_addr(func_env, builder, array_type_index, array_ref, index); - let array_ty = func_env.types[array_type_index] - .composite_type - .unwrap_array(); + let array_ty = func_env.types.unwrap_array(array_type_index)?; let elem_ty = array_ty.0.element_type; read_field_at_addr(func_env, builder, elem_ty, elem_addr, Some(Extension::Zero)) @@ -920,9 +896,7 @@ pub fn translate_array_set( let array_type_index = func_env.module.types[array_type_index]; let elem_addr = array_elem_addr(func_env, builder, array_type_index, array_ref, index); - let array_ty = func_env.types[array_type_index] - .composite_type - .unwrap_array(); + let array_ty = func_env.types.unwrap_array(array_type_index)?; let elem_ty = array_ty.0.element_type; write_field_at_addr(func_env, builder, elem_ty, elem_addr, value) @@ -1263,7 +1237,11 @@ fn initialize_struct_fields( let field_offsets: SmallVec<[_; 8]> = struct_layout.fields.iter().copied().collect(); assert_eq!(field_offsets.len(), field_values.len()); - let struct_ty = func_env.types[struct_ty].composite_type.unwrap_struct(); + assert!(!func_env.types[struct_ty].composite_type.shared); + let struct_ty = func_env.types[struct_ty] + .composite_type + .inner + .unwrap_struct(); let field_types: SmallVec<[_; 8]> = struct_ty.fields.iter().cloned().collect(); assert_eq!(field_types.len(), field_values.len()); diff --git a/crates/environ/src/compile/module_types.rs b/crates/environ/src/compile/module_types.rs index e25c7c6de57e..b8c32f7fe8c7 100644 --- a/crates/environ/src/compile/module_types.rs +++ b/crates/environ/src/compile/module_types.rs @@ -1,7 +1,8 @@ use crate::{ - EngineOrModuleTypeIndex, EntityRef, ModuleInternedRecGroupIndex, ModuleInternedTypeIndex, - ModuleTypes, TypeConvert, TypeIndex, WasmCompositeType, WasmFuncType, WasmHeapType, WasmResult, - WasmSubType, + wasm_unsupported, EngineOrModuleTypeIndex, EntityRef, ModuleInternedRecGroupIndex, + ModuleInternedTypeIndex, ModuleTypes, TypeConvert, TypeIndex, WasmArrayType, + WasmCompositeInnerType, WasmCompositeType, WasmFuncType, WasmHeapType, WasmResult, + WasmStructType, WasmSubType, }; use std::{borrow::Cow, collections::HashMap, ops::Index}; use wasmparser::{UnpackedIndex, Validator, ValidatorId}; @@ -140,7 +141,8 @@ impl ModuleTypesBuilder { &mut self, for_func_ty: ModuleInternedTypeIndex, ) -> ModuleInternedTypeIndex { - let trampoline = self.types[for_func_ty].unwrap_func().trampoline_type(); + let sub_ty = &self.types[for_func_ty]; + let trampoline = sub_ty.unwrap_func().trampoline_type(); if let Some(idx) = self.trampoline_types.get(&trampoline) { // We've already interned this trampoline type; reuse it. @@ -163,7 +165,10 @@ impl ModuleTypesBuilder { let idx = self.types.push(WasmSubType { is_final: true, supertype: None, - composite_type: WasmCompositeType::Func(f.clone()), + composite_type: WasmCompositeType { + inner: WasmCompositeInnerType::Func(f.clone()), + shared: sub_ty.composite_type.shared, + }, }); // The trampoline type is its own trampoline type. @@ -325,6 +330,46 @@ impl ModuleTypesBuilder { pub fn trampoline_type(&self, ty: ModuleInternedTypeIndex) -> ModuleInternedTypeIndex { self.types.trampoline_type(ty) } + + /// Get and unwrap a [`WasmStructType`] for the given struct index. + /// + /// # Panics + /// + /// Panics if the unwrapped type is not a struct. + /// + /// # Errors + /// + /// For now, fails with an unsupported error if the type is shared. + pub fn unwrap_struct(&self, ty: ModuleInternedTypeIndex) -> WasmResult<&WasmStructType> { + let composite_type = &self.types[ty].composite_type; + if composite_type.shared { + return Err(wasm_unsupported!("shared structs are not yet implemented")); + } + match &composite_type.inner { + WasmCompositeInnerType::Struct(s) => Ok(s), + _ => unreachable!(), + } + } + + /// Get and unwrap a [`WasmArrayType`] for the given array index. + /// + /// # Panics + /// + /// Panics if the unwrapped type is not an array. + /// + /// # Errors + /// + /// For now, fails with an unsupported error if the type is shared. + pub fn unwrap_array(&self, interned_ty: ModuleInternedTypeIndex) -> WasmResult<&WasmArrayType> { + let composite_type = &self.types[interned_ty].composite_type; + if composite_type.shared { + return Err(wasm_unsupported!("shared arrays are not yet implemented")); + } + match &composite_type.inner { + WasmCompositeInnerType::Array(a) => Ok(a), + _ => unreachable!(), + } + } } // Forward the indexing impl to the internal `ModuleTypes` @@ -388,10 +433,11 @@ where // array vs struct vs func reference. In this case, we can use // the validator's type context. if let Some(ty) = self.types.types.get(interned) { - match &ty.composite_type { - WasmCompositeType::Array(_) => WasmHeapType::ConcreteArray(index), - WasmCompositeType::Func(_) => WasmHeapType::ConcreteFunc(index), - WasmCompositeType::Struct(_) => WasmHeapType::ConcreteStruct(index), + assert!(!ty.composite_type.shared); + match &ty.composite_type.inner { + WasmCompositeInnerType::Array(_) => WasmHeapType::ConcreteArray(index), + WasmCompositeInnerType::Func(_) => WasmHeapType::ConcreteFunc(index), + WasmCompositeInnerType::Struct(_) => WasmHeapType::ConcreteStruct(index), } } else if let Some((wasmparser_types, _)) = self.rec_group_context.as_ref() { let wasmparser_ty = &wasmparser_types[id].composite_type; @@ -426,10 +472,11 @@ where // indirectly get one by looking it up inside the current rec // group. if let Some(ty) = self.types.types.get(interned) { - match &ty.composite_type { - WasmCompositeType::Array(_) => WasmHeapType::ConcreteArray(index), - WasmCompositeType::Func(_) => WasmHeapType::ConcreteFunc(index), - WasmCompositeType::Struct(_) => WasmHeapType::ConcreteStruct(index), + assert!(!ty.composite_type.shared); + match &ty.composite_type.inner { + WasmCompositeInnerType::Array(_) => WasmHeapType::ConcreteArray(index), + WasmCompositeInnerType::Func(_) => WasmHeapType::ConcreteFunc(index), + WasmCompositeInnerType::Struct(_) => WasmHeapType::ConcreteStruct(index), } } else if let Some((parser_types, rec_group)) = self.rec_group_context.as_ref() { let rec_group_index = interned.index() - self.types.types.len_types(); diff --git a/crates/environ/src/gc.rs b/crates/environ/src/gc.rs index 173031f1d7bc..38be69f85fcd 100644 --- a/crates/environ/src/gc.rs +++ b/crates/environ/src/gc.rs @@ -16,7 +16,10 @@ pub mod drc; pub mod null; use crate::prelude::*; -use crate::{WasmArrayType, WasmCompositeType, WasmStorageType, WasmStructType, WasmValType}; +use crate::{ + WasmArrayType, WasmCompositeInnerType, WasmCompositeType, WasmStorageType, WasmStructType, + WasmValType, +}; use core::alloc::Layout; /// Discriminant to check whether GC reference is an `i31ref` or not. @@ -158,10 +161,11 @@ pub trait GcTypeLayouts { /// Returns `None` if the type is a function type, as functions are not /// managed by the GC. fn gc_layout(&self, ty: &WasmCompositeType) -> Option { - match ty { - WasmCompositeType::Array(ty) => Some(self.array_layout(ty).into()), - WasmCompositeType::Struct(ty) => Some(self.struct_layout(ty).into()), - WasmCompositeType::Func(_) => None, + assert!(!ty.shared); + match &ty.inner { + WasmCompositeInnerType::Array(ty) => Some(self.array_layout(ty).into()), + WasmCompositeInnerType::Struct(ty) => Some(self.struct_layout(ty).into()), + WasmCompositeInnerType::Func(_) => None, } } diff --git a/crates/environ/src/types.rs b/crates/environ/src/types.rs index 0b7d64a350a1..677ee0d2224e 100644 --- a/crates/environ/src/types.rs +++ b/crates/environ/src/types.rs @@ -885,27 +885,50 @@ impl TypeTrace for WasmStructType { } } +#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] +#[allow(missing_docs)] +pub struct WasmCompositeType { + /// The type defined inside the composite type. + pub inner: WasmCompositeInnerType, + /// Is the composite type shared? This is part of the + /// shared-everything-threads proposal. + pub shared: bool, +} + +impl fmt::Display for WasmCompositeType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.shared { + write!(f, "(shared ")?; + } + fmt::Display::fmt(&self.inner, f)?; + if self.shared { + write!(f, ")")?; + } + Ok(()) + } +} + /// A function, array, or struct type. #[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[allow(missing_docs)] -pub enum WasmCompositeType { +pub enum WasmCompositeInnerType { Array(WasmArrayType), Func(WasmFuncType), Struct(WasmStructType), } -impl fmt::Display for WasmCompositeType { +impl fmt::Display for WasmCompositeInnerType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - WasmCompositeType::Array(ty) => fmt::Display::fmt(ty, f), - WasmCompositeType::Func(ty) => fmt::Display::fmt(ty, f), - WasmCompositeType::Struct(ty) => fmt::Display::fmt(ty, f), + Self::Array(ty) => fmt::Display::fmt(ty, f), + Self::Func(ty) => fmt::Display::fmt(ty, f), + Self::Struct(ty) => fmt::Display::fmt(ty, f), } } } #[allow(missing_docs)] -impl WasmCompositeType { +impl WasmCompositeInnerType { #[inline] pub fn is_array(&self) -> bool { matches!(self, Self::Array(_)) @@ -914,7 +937,7 @@ impl WasmCompositeType { #[inline] pub fn as_array(&self) -> Option<&WasmArrayType> { match self { - WasmCompositeType::Array(f) => Some(f), + Self::Array(f) => Some(f), _ => None, } } @@ -932,7 +955,7 @@ impl WasmCompositeType { #[inline] pub fn as_func(&self) -> Option<&WasmFuncType> { match self { - WasmCompositeType::Func(f) => Some(f), + Self::Func(f) => Some(f), _ => None, } } @@ -950,7 +973,7 @@ impl WasmCompositeType { #[inline] pub fn as_struct(&self) -> Option<&WasmStructType> { match self { - WasmCompositeType::Struct(f) => Some(f), + Self::Struct(f) => Some(f), _ => None, } } @@ -966,10 +989,10 @@ impl TypeTrace for WasmCompositeType { where F: FnMut(EngineOrModuleTypeIndex) -> Result<(), E>, { - match self { - WasmCompositeType::Array(a) => a.trace(func), - WasmCompositeType::Func(f) => f.trace(func), - WasmCompositeType::Struct(a) => a.trace(func), + match &self.inner { + WasmCompositeInnerType::Array(a) => a.trace(func), + WasmCompositeInnerType::Func(f) => f.trace(func), + WasmCompositeInnerType::Struct(a) => a.trace(func), } } @@ -977,10 +1000,10 @@ impl TypeTrace for WasmCompositeType { where F: FnMut(&mut EngineOrModuleTypeIndex) -> Result<(), E>, { - match self { - WasmCompositeType::Array(a) => a.trace_mut(func), - WasmCompositeType::Func(f) => f.trace_mut(func), - WasmCompositeType::Struct(a) => a.trace_mut(func), + match &mut self.inner { + WasmCompositeInnerType::Array(a) => a.trace_mut(func), + WasmCompositeInnerType::Func(f) => f.trace_mut(func), + WasmCompositeInnerType::Struct(a) => a.trace_mut(func), } } } @@ -1016,51 +1039,69 @@ impl fmt::Display for WasmSubType { } } +/// Implicitly define all of these helper functions to handle only unshared +/// types; essentially, these act like `is_unshared_*` functions until shared +/// support is implemented. #[allow(missing_docs)] impl WasmSubType { #[inline] pub fn is_func(&self) -> bool { - self.composite_type.is_func() + self.composite_type.inner.is_func() && !self.composite_type.shared } #[inline] pub fn as_func(&self) -> Option<&WasmFuncType> { - self.composite_type.as_func() + if self.composite_type.shared { + None + } else { + self.composite_type.inner.as_func() + } } #[inline] pub fn unwrap_func(&self) -> &WasmFuncType { - self.composite_type.unwrap_func() + assert!(!self.composite_type.shared); + self.composite_type.inner.unwrap_func() } #[inline] pub fn is_array(&self) -> bool { - self.composite_type.is_array() + self.composite_type.inner.is_array() && !self.composite_type.shared } #[inline] pub fn as_array(&self) -> Option<&WasmArrayType> { - self.composite_type.as_array() + if self.composite_type.shared { + None + } else { + self.composite_type.inner.as_array() + } } #[inline] pub fn unwrap_array(&self) -> &WasmArrayType { - self.composite_type.unwrap_array() + assert!(!self.composite_type.shared); + self.composite_type.inner.unwrap_array() } #[inline] pub fn is_struct(&self) -> bool { - self.composite_type.is_struct() + self.composite_type.inner.is_struct() && !self.composite_type.shared } #[inline] pub fn as_struct(&self) -> Option<&WasmStructType> { - self.composite_type.as_struct() + if self.composite_type.shared { + None + } else { + self.composite_type.inner.as_struct() + } } #[inline] pub fn unwrap_struct(&self) -> &WasmStructType { - self.composite_type.unwrap_struct() + assert!(!self.composite_type.shared); + self.composite_type.inner.unwrap_struct() } } @@ -1849,20 +1890,23 @@ pub trait TypeConvert { } fn convert_composite_type(&self, ty: &wasmparser::CompositeType) -> WasmCompositeType { - assert!(!ty.shared); - match &ty.inner { + let inner = match &ty.inner { wasmparser::CompositeInnerType::Func(f) => { - WasmCompositeType::Func(self.convert_func_type(f)) + WasmCompositeInnerType::Func(self.convert_func_type(f)) } wasmparser::CompositeInnerType::Array(a) => { - WasmCompositeType::Array(self.convert_array_type(a)) + WasmCompositeInnerType::Array(self.convert_array_type(a)) } wasmparser::CompositeInnerType::Struct(s) => { - WasmCompositeType::Struct(self.convert_struct_type(s)) + WasmCompositeInnerType::Struct(self.convert_struct_type(s)) } wasmparser::CompositeInnerType::Cont(_) => { unimplemented!("continuation types") } + }; + WasmCompositeType { + inner, + shared: ty.shared, } } diff --git a/crates/wasmtime/src/runtime/type_registry.rs b/crates/wasmtime/src/runtime/type_registry.rs index 82f855f09992..cdbfa6d42fb0 100644 --- a/crates/wasmtime/src/runtime/type_registry.rs +++ b/crates/wasmtime/src/runtime/type_registry.rs @@ -737,9 +737,12 @@ impl TypeRegistryInner { WasmSubType { is_final: true, supertype: None, - composite_type: wasmtime_environ::WasmCompositeType::Func( - trampoline.into_owned(), - ), + composite_type: wasmtime_environ::WasmCompositeType { + shared: sub_ty.composite_type.shared, + inner: wasmtime_environ::WasmCompositeInnerType::Func( + trampoline.into_owned(), + ), + }, }, ); let trampoline_index = trampoline_entry.0.shared_type_indices[0]; @@ -806,16 +809,17 @@ impl TypeRegistryInner { "type is not canonicalized for runtime usage: {ty:?}" ); - let gc_layout = match &ty.composite_type { - wasmtime_environ::WasmCompositeType::Func(_) => None, - wasmtime_environ::WasmCompositeType::Array(a) => Some( + assert!(!ty.composite_type.shared); + let gc_layout = match &ty.composite_type.inner { + wasmtime_environ::WasmCompositeInnerType::Func(_) => None, + wasmtime_environ::WasmCompositeInnerType::Array(a) => Some( gc_runtime .expect("must have a GC runtime to register array types") .layouts() .array_layout(a) .into(), ), - wasmtime_environ::WasmCompositeType::Struct(s) => Some( + wasmtime_environ::WasmCompositeInnerType::Struct(s) => Some( gc_runtime .expect("must have a GC runtime to register array types") .layouts() diff --git a/crates/wasmtime/src/runtime/types.rs b/crates/wasmtime/src/runtime/types.rs index 9c2a5ccf1f26..1fa7743061c3 100644 --- a/crates/wasmtime/src/runtime/types.rs +++ b/crates/wasmtime/src/runtime/types.rs @@ -2,8 +2,9 @@ use crate::prelude::*; use core::fmt::{self, Display, Write}; use wasmtime_environ::{ EngineOrModuleTypeIndex, EntityType, Global, IndexType, Limits, Memory, ModuleTypes, Table, - TypeTrace, VMSharedTypeIndex, WasmArrayType, WasmCompositeType, WasmFieldType, WasmFuncType, - WasmHeapType, WasmRefType, WasmStorageType, WasmStructType, WasmSubType, WasmValType, + TypeTrace, VMSharedTypeIndex, WasmArrayType, WasmCompositeInnerType, WasmCompositeType, + WasmFieldType, WasmFuncType, WasmHeapType, WasmRefType, WasmStorageType, WasmStructType, + WasmSubType, WasmValType, }; use crate::{type_registry::RegisteredType, Engine}; @@ -1617,6 +1618,7 @@ impl StructType { Self::from_wasm_struct_type( engine, finality.is_final(), + false, supertype.map(|ty| ty.type_index().into()), WasmStructType { fields }, ) @@ -1733,6 +1735,7 @@ impl StructType { pub(crate) fn from_wasm_struct_type( engine: &Engine, is_final: bool, + is_shared: bool, supertype: Option, ty: WasmStructType, ) -> Result { @@ -1750,7 +1753,10 @@ impl StructType { WasmSubType { is_final, supertype, - composite_type: WasmCompositeType::Struct(ty), + composite_type: WasmCompositeType { + shared: is_shared, + inner: WasmCompositeInnerType::Struct(ty), + }, }, ); Ok(Self { @@ -1994,7 +2000,10 @@ impl ArrayType { WasmSubType { is_final, supertype, - composite_type: WasmCompositeType::Array(ty), + composite_type: WasmCompositeType { + shared: false, + inner: WasmCompositeInnerType::Array(ty), + }, }, ); Self { @@ -2350,7 +2359,10 @@ impl FuncType { WasmSubType { is_final, supertype, - composite_type: WasmCompositeType::Func(ty), + composite_type: WasmCompositeType { + shared: false, + inner: WasmCompositeInnerType::Func(ty), + }, }, ); Self { diff --git a/crates/wasmtime/src/runtime/vm/const_expr.rs b/crates/wasmtime/src/runtime/vm/const_expr.rs index 0ffab2720e37..55b4a2c63081 100644 --- a/crates/wasmtime/src/runtime/vm/const_expr.rs +++ b/crates/wasmtime/src/runtime/vm/const_expr.rs @@ -7,8 +7,8 @@ use crate::{ }; use smallvec::SmallVec; use wasmtime_environ::{ - ConstExpr, ConstOp, FuncIndex, GlobalIndex, ModuleInternedTypeIndex, WasmCompositeType, - WasmSubType, + ConstExpr, ConstOp, FuncIndex, GlobalIndex, ModuleInternedTypeIndex, WasmCompositeInnerType, + WasmCompositeType, WasmSubType, }; /// An interpreter for const expressions. @@ -55,8 +55,8 @@ impl<'a> ConstEvalContext<'a> { .runtime_module() .expect("should never be allocating a struct type defined in a dummy module"); - let struct_ty = match &module.types()[struct_type_index].composite_type { - WasmCompositeType::Struct(s) => s, + let struct_ty = match &module.types()[struct_type_index].composite_type.inner { + WasmCompositeInnerType::Struct(s) => s, _ => unreachable!(), }; @@ -118,7 +118,11 @@ impl<'a> ConstEvalContext<'a> { .borrow(shared_ty) .expect("should have a registered type for struct"); let WasmSubType { - composite_type: WasmCompositeType::Struct(struct_ty), + composite_type: + WasmCompositeType { + shared: false, + inner: WasmCompositeInnerType::Struct(struct_ty), + }, .. } = &*borrowed else {