diff --git a/crates/cranelift/src/func_environ.rs b/crates/cranelift/src/func_environ.rs index 775ad82e1142..67ed54a28a34 100644 --- a/crates/cranelift/src/func_environ.rs +++ b/crates/cranelift/src/func_environ.rs @@ -1458,6 +1458,8 @@ impl<'a, 'func, 'module_env> Call<'a, 'func, 'module_env> { return CheckIndirectCallTypeSignature::StaticTrap; } + WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => todo!(), // FIXME: #10248 stack switching support. + // Engine-indexed types don't show up until runtime and it's a Wasm // validation error to perform a call through a non-function table, // so these cases are dynamically not reachable. @@ -1701,6 +1703,7 @@ impl<'module_environment> TargetEnvironment for FuncEnvironment<'module_environm let needs_stack_map = match wasm_ty.top() { WasmHeapTopType::Extern | WasmHeapTopType::Any => true, WasmHeapTopType::Func => false, + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. }; (ty, needs_stack_map) } @@ -1816,6 +1819,9 @@ impl FuncEnvironment<'_> { WasmHeapTopType::Func => { Ok(self.get_or_init_func_ref_table_elem(builder, table_index, index, false)) } + + // Continuation types. + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. } } @@ -1862,6 +1868,9 @@ impl FuncEnvironment<'_> { .store(flags, value_with_init_bit, elem_addr, 0); Ok(()) } + + // Continuation types. + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. } } @@ -2213,6 +2222,7 @@ impl FuncEnvironment<'_> { WasmHeapTopType::Func => pos.ins().iconst(self.pointer_type(), 0), // NB: null GC references don't need to be in stack maps. WasmHeapTopType::Any | WasmHeapTopType::Extern => pos.ins().iconst(types::I32, 0), + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. }) } diff --git a/crates/cranelift/src/gc/enabled.rs b/crates/cranelift/src/gc/enabled.rs index 9746b31e87c4..3e769d221545 100644 --- a/crates/cranelift/src/gc/enabled.rs +++ b/crates/cranelift/src/gc/enabled.rs @@ -148,6 +148,7 @@ fn read_field_at_addr( .call(get_interned_func_ref, &[vmctx, func_ref_id, expected_ty]); builder.func.dfg.first_result(call_inst) } + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. }, }, }; @@ -1059,6 +1060,8 @@ pub fn translate_ref_test( func_env.is_subtype(builder, actual_shared_ty, expected_shared_ty) } + + WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => todo!(), // FIXME: #10248 stack switching support. }; builder.ins().jump(continue_block, &[result]); @@ -1391,6 +1394,8 @@ impl FuncEnvironment<'_> { WasmHeapType::Func | WasmHeapType::ConcreteFunc(_) | WasmHeapType::NoFunc => { unreachable!() } + + WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => todo!(), // FIXME: #10248 stack switching support. }; match (ty.nullable, might_be_i31) { diff --git a/crates/cranelift/src/lib.rs b/crates/cranelift/src/lib.rs index cd60ba6f3531..a98a9c04b77d 100644 --- a/crates/cranelift/src/lib.rs +++ b/crates/cranelift/src/lib.rs @@ -202,6 +202,7 @@ fn reference_type(wasm_ht: WasmHeapType, pointer_type: ir::Type) -> ir::Type { match wasm_ht.top() { WasmHeapTopType::Func => pointer_type, WasmHeapTopType::Any | WasmHeapTopType::Extern => ir::types::I32, + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. } } diff --git a/crates/environ/src/compile/module_environ.rs b/crates/environ/src/compile/module_environ.rs index 9f0a71c1a943..15dcace44202 100644 --- a/crates/environ/src/compile/module_environ.rs +++ b/crates/environ/src/compile/module_environ.rs @@ -1220,7 +1220,7 @@ impl ModuleTranslation<'_> { // initializer won't trap so we could continue processing // segments, but that's left as a future optimization if // necessary. - WasmHeapTopType::Any | WasmHeapTopType::Extern => break, + WasmHeapTopType::Any | WasmHeapTopType::Extern | WasmHeapTopType::Cont => break, } // Function indices can be optimized here, but fully general diff --git a/crates/environ/src/compile/module_types.rs b/crates/environ/src/compile/module_types.rs index 045786d436e1..470d2193e1e8 100644 --- a/crates/environ/src/compile/module_types.rs +++ b/crates/environ/src/compile/module_types.rs @@ -438,6 +438,7 @@ where WasmCompositeInnerType::Array(_) => WasmHeapType::ConcreteArray(index), WasmCompositeInnerType::Func(_) => WasmHeapType::ConcreteFunc(index), WasmCompositeInnerType::Struct(_) => WasmHeapType::ConcreteStruct(index), + WasmCompositeInnerType::Cont(_) => WasmHeapType::ConcreteCont(index), } } else if let Some((wasmparser_types, _)) = self.rec_group_context.as_ref() { let wasmparser_ty = &wasmparser_types[id].composite_type; @@ -453,7 +454,7 @@ where WasmHeapType::ConcreteStruct(index) } wasmparser::CompositeInnerType::Cont(_) => { - panic!("unimplemented continuation types") + WasmHeapType::ConcreteCont(index) } } } else { @@ -477,6 +478,7 @@ where WasmCompositeInnerType::Array(_) => WasmHeapType::ConcreteArray(index), WasmCompositeInnerType::Func(_) => WasmHeapType::ConcreteFunc(index), WasmCompositeInnerType::Struct(_) => WasmHeapType::ConcreteStruct(index), + WasmCompositeInnerType::Cont(_) => WasmHeapType::ConcreteCont(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(); @@ -497,7 +499,7 @@ where WasmHeapType::ConcreteStruct(index) } wasmparser::CompositeInnerType::Cont(_) => { - panic!("unimplemented continuation types") + WasmHeapType::ConcreteCont(index) } } } else { diff --git a/crates/environ/src/gc.rs b/crates/environ/src/gc.rs index 970e8e5ae098..4fa7d8745bab 100644 --- a/crates/environ/src/gc.rs +++ b/crates/environ/src/gc.rs @@ -162,6 +162,7 @@ pub trait GcTypeLayouts { WasmCompositeInnerType::Array(ty) => Some(self.array_layout(ty).into()), WasmCompositeInnerType::Struct(ty) => Some(self.struct_layout(ty).into()), WasmCompositeInnerType::Func(_) => None, + WasmCompositeInnerType::Cont(_) => None, } } diff --git a/crates/environ/src/types.rs b/crates/environ/src/types.rs index 0eeba147891a..14829377ea43 100644 --- a/crates/environ/src/types.rs +++ b/crates/environ/src/types.rs @@ -436,6 +436,11 @@ pub enum WasmHeapType { ConcreteFunc(EngineOrModuleTypeIndex), NoFunc, + // Continuation types. + Cont, + ConcreteCont(EngineOrModuleTypeIndex), + NoCont, + // Internal types. Any, Eq, @@ -454,6 +459,7 @@ impl From for WasmHeapType { WasmHeapTopType::Extern => Self::Extern, WasmHeapTopType::Any => Self::Any, WasmHeapTopType::Func => Self::Func, + WasmHeapTopType::Cont => Self::Cont, } } } @@ -465,6 +471,7 @@ impl From for WasmHeapType { WasmHeapBottomType::NoExtern => Self::NoExtern, WasmHeapBottomType::None => Self::None, WasmHeapBottomType::NoFunc => Self::NoFunc, + WasmHeapBottomType::NoCont => Self::NoCont, } } } @@ -477,6 +484,9 @@ impl fmt::Display for WasmHeapType { Self::Func => write!(f, "func"), Self::ConcreteFunc(i) => write!(f, "func {i}"), Self::NoFunc => write!(f, "nofunc"), + Self::Cont => write!(f, "cont"), + Self::ConcreteCont(i) => write!(f, "cont {i}"), + Self::NoCont => write!(f, "nocont"), Self::Any => write!(f, "any"), Self::Eq => write!(f, "eq"), Self::I31 => write!(f, "i31"), @@ -498,6 +508,7 @@ impl TypeTrace for WasmHeapType { Self::ConcreteArray(i) => func(i), Self::ConcreteFunc(i) => func(i), Self::ConcreteStruct(i) => func(i), + Self::ConcreteCont(i) => func(i), _ => Ok(()), } } @@ -510,6 +521,7 @@ impl TypeTrace for WasmHeapType { Self::ConcreteArray(i) => func(i), Self::ConcreteFunc(i) => func(i), Self::ConcreteStruct(i) => func(i), + Self::ConcreteCont(i) => func(i), _ => Ok(()), } } @@ -526,6 +538,7 @@ impl WasmHeapType { // All `t <: (ref null func)` are not. WasmHeapTopType::Func => false, + WasmHeapTopType::Cont => false, } } @@ -555,6 +568,10 @@ impl WasmHeapType { WasmHeapTopType::Func } + WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => { + WasmHeapTopType::Cont + } + WasmHeapType::Any | WasmHeapType::Eq | WasmHeapType::I31 @@ -582,6 +599,10 @@ impl WasmHeapType { WasmHeapBottomType::NoFunc } + WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => { + WasmHeapBottomType::NoCont + } + WasmHeapType::Any | WasmHeapType::Eq | WasmHeapType::I31 @@ -603,6 +624,8 @@ pub enum WasmHeapTopType { Any, /// The common supertype of all function references. Func, + /// The common supertype of all continuation references. + Cont, } /// A bottom heap type. @@ -614,6 +637,8 @@ pub enum WasmHeapBottomType { None, /// The common subtype of all function references. NoFunc, + /// The common subtype of all continuation references. + NoCont, } /// WebAssembly function type -- equivalent of `wasmparser`'s FuncType. @@ -761,6 +786,39 @@ impl WasmFuncType { } } +/// WebAssembly continuation type -- equivalent of `wasmparser`'s ContType. +#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] +pub struct WasmContType(EngineOrModuleTypeIndex); + +impl fmt::Display for WasmContType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "(cont {})", self.0) + } +} + +impl WasmContType { + /// Constructs a new continuation type. + pub fn new(idx: EngineOrModuleTypeIndex) -> Self { + WasmContType(idx) + } +} + +impl TypeTrace for WasmContType { + fn trace(&self, func: &mut F) -> Result<(), E> + where + F: FnMut(EngineOrModuleTypeIndex) -> Result<(), E>, + { + func(self.0) + } + + fn trace_mut(&mut self, func: &mut F) -> Result<(), E> + where + F: FnMut(&mut EngineOrModuleTypeIndex) -> Result<(), E>, + { + func(&mut self.0) + } +} + /// Represents storage types introduced in the GC spec for array and struct fields. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] pub enum WasmStorageType { @@ -935,6 +993,7 @@ pub enum WasmCompositeInnerType { Array(WasmArrayType), Func(WasmFuncType), Struct(WasmStructType), + Cont(WasmContType), } impl fmt::Display for WasmCompositeInnerType { @@ -943,6 +1002,7 @@ impl fmt::Display for WasmCompositeInnerType { Self::Array(ty) => fmt::Display::fmt(ty, f), Self::Func(ty) => fmt::Display::fmt(ty, f), Self::Struct(ty) => fmt::Display::fmt(ty, f), + Self::Cont(ty) => fmt::Display::fmt(ty, f), } } } @@ -1002,6 +1062,24 @@ impl WasmCompositeInnerType { pub fn unwrap_struct(&self) -> &WasmStructType { self.as_struct().unwrap() } + + #[inline] + pub fn is_cont(&self) -> bool { + matches!(self, Self::Cont(_)) + } + + #[inline] + pub fn as_cont(&self) -> Option<&WasmContType> { + match self { + Self::Cont(f) => Some(f), + _ => None, + } + } + + #[inline] + pub fn unwrap_cont(&self) -> &WasmContType { + self.as_cont().unwrap() + } } impl TypeTrace for WasmCompositeType { @@ -1013,6 +1091,7 @@ impl TypeTrace for WasmCompositeType { WasmCompositeInnerType::Array(a) => a.trace(func), WasmCompositeInnerType::Func(f) => f.trace(func), WasmCompositeInnerType::Struct(a) => a.trace(func), + WasmCompositeInnerType::Cont(c) => c.trace(func), } } @@ -1024,6 +1103,7 @@ impl TypeTrace for WasmCompositeType { WasmCompositeInnerType::Array(a) => a.trace_mut(func), WasmCompositeInnerType::Func(f) => f.trace_mut(func), WasmCompositeInnerType::Struct(a) => a.trace_mut(func), + WasmCompositeInnerType::Cont(c) => c.trace_mut(func), } } } @@ -1123,6 +1203,26 @@ impl WasmSubType { assert!(!self.composite_type.shared); self.composite_type.inner.unwrap_struct() } + + #[inline] + pub fn is_cont(&self) -> bool { + self.composite_type.inner.is_cont() && !self.composite_type.shared + } + + #[inline] + pub fn as_cont(&self) -> Option<&WasmContType> { + if self.composite_type.shared { + None + } else { + self.composite_type.inner.as_cont() + } + } + + #[inline] + pub fn unwrap_cont(&self) -> &WasmContType { + assert!(!self.composite_type.shared); + self.composite_type.inner.unwrap_cont() + } } impl TypeTrace for WasmSubType { @@ -2018,8 +2118,8 @@ pub trait TypeConvert { wasmparser::CompositeInnerType::Struct(s) => { WasmCompositeInnerType::Struct(self.convert_struct_type(s)) } - wasmparser::CompositeInnerType::Cont(_) => { - unimplemented!("continuation types") + wasmparser::CompositeInnerType::Cont(c) => { + WasmCompositeInnerType::Cont(self.convert_cont_type(c)) } }; WasmCompositeType { @@ -2028,6 +2128,15 @@ pub trait TypeConvert { } } + /// Converts a wasmparser continuation type to a wasmtime type + fn convert_cont_type(&self, ty: &wasmparser::ContType) -> WasmContType { + if let WasmHeapType::ConcreteFunc(sigidx) = self.lookup_heap_type(ty.0.unpack()) { + WasmContType::new(sigidx) + } else { + panic!("Failed to extract signature index for continuation type.") + } + } + fn convert_struct_type(&self, ty: &wasmparser::StructType) -> WasmStructType { WasmStructType { fields: ty diff --git a/crates/wasmtime/src/runtime/type_registry.rs b/crates/wasmtime/src/runtime/type_registry.rs index 7b8c768c7f41..ded58a1f9e99 100644 --- a/crates/wasmtime/src/runtime/type_registry.rs +++ b/crates/wasmtime/src/runtime/type_registry.rs @@ -851,6 +851,7 @@ impl TypeRegistryInner { .struct_layout(s) .into(), ), + wasmtime_environ::WasmCompositeInnerType::Cont(_) => todo!(), // FIXME: #10248 stack switching support. }; // Add the type to our slab. diff --git a/crates/wasmtime/src/runtime/types.rs b/crates/wasmtime/src/runtime/types.rs index 851b0e74cd0f..af59413ee6df 100644 --- a/crates/wasmtime/src/runtime/types.rs +++ b/crates/wasmtime/src/runtime/types.rs @@ -1096,6 +1096,8 @@ impl HeapType { | WasmHeapType::ConcreteStruct(EngineOrModuleTypeIndex::RecGroup(_)) => { panic!("HeapType::from_wasm_type on non-canonicalized-for-runtime-usage heap type") } + + WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => todo!(), // FIXME: #10248 stack switching support. } } diff --git a/crates/wasmtime/src/runtime/types/matching.rs b/crates/wasmtime/src/runtime/types/matching.rs index e4d2557ba700..a038c410f0d5 100644 --- a/crates/wasmtime/src/runtime/types/matching.rs +++ b/crates/wasmtime/src/runtime/types/matching.rs @@ -187,6 +187,7 @@ fn match_heap(expected: WasmHeapType, actual: WasmHeapType, desc: &str) -> Resul (H::ConcreteArray(actual), H::ConcreteArray(expected)) => actual == expected, (H::ConcreteFunc(actual), H::ConcreteFunc(expected)) => actual == expected, (H::ConcreteStruct(actual), H::ConcreteStruct(expected)) => actual == expected, + (H::ConcreteCont(actual), H::ConcreteCont(expected)) => actual == expected, (H::NoFunc, H::NoFunc) => true, (_, H::NoFunc) => false, @@ -243,6 +244,15 @@ fn match_heap(expected: WasmHeapType, actual: WasmHeapType, desc: &str) -> Resul (H::None, H::ConcreteStruct(_)) => true, (_, H::ConcreteStruct(_)) => false, + (H::NoCont | H::ConcreteCont(_) | H::Cont, H::Cont) => true, + (_, H::Cont) => false, + + (H::NoCont, H::ConcreteCont(_)) => true, + (H::NoCont, H::NoCont) => true, + + (_, H::NoCont) => false, + (_, H::ConcreteCont(_)) => false, + (H::None, H::None) => true, (_, H::None) => false, }; diff --git a/crates/wasmtime/src/runtime/vm/instance.rs b/crates/wasmtime/src/runtime/vm/instance.rs index f0e2e051bd12..bbaff01573ad 100644 --- a/crates/wasmtime/src/runtime/vm/instance.rs +++ b/crates/wasmtime/src/runtime/vm/instance.rs @@ -1088,6 +1088,7 @@ impl Instance { ) }), )?, + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. } } } diff --git a/crates/wasmtime/src/runtime/vm/instance/allocator.rs b/crates/wasmtime/src/runtime/vm/instance/allocator.rs index 229f5e3eb89b..3247c81bac6d 100644 --- a/crates/wasmtime/src/runtime/vm/instance/allocator.rs +++ b/crates/wasmtime/src/runtime/vm/instance/allocator.rs @@ -606,6 +606,8 @@ fn initialize_tables( let items = (0..table.size()).map(|_| funcref); table.init_func(0, items)?; } + + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. } } } diff --git a/crates/wasmtime/src/runtime/vm/table.rs b/crates/wasmtime/src/runtime/vm/table.rs index 929f46347ab8..c18b861578e1 100644 --- a/crates/wasmtime/src/runtime/vm/table.rs +++ b/crates/wasmtime/src/runtime/vm/table.rs @@ -263,6 +263,7 @@ fn wasm_to_table_type(ty: WasmRefType) -> TableElementType { match ty.heap_type.top() { WasmHeapTopType::Func => TableElementType::Func, WasmHeapTopType::Any | WasmHeapTopType::Extern => TableElementType::GcRef, + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. } } diff --git a/crates/wasmtime/src/runtime/vm/vmcontext.rs b/crates/wasmtime/src/runtime/vm/vmcontext.rs index 53b45a95d65c..fd4e0a11b52b 100644 --- a/crates/wasmtime/src/runtime/vm/vmcontext.rs +++ b/crates/wasmtime/src/runtime/vm/vmcontext.rs @@ -500,6 +500,7 @@ impl VMGlobalDefinition { global.init_gc_ref(store.gc_store_mut()?, r.as_ref()) } WasmHeapTopType::Func => *global.as_func_ref_mut() = raw.get_funcref().cast(), + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. }, } Ok(global) @@ -533,6 +534,7 @@ impl VMGlobalDefinition { } }), WasmHeapTopType::Func => ValRaw::funcref(self.as_func_ref().cast()), + WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support. }, }) }