Skip to content

Continuation types #10255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions crates/cranelift/src/func_environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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.
}
}

Expand Down Expand Up @@ -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.
}
}

Expand Down Expand Up @@ -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.
})
}

Expand Down
5 changes: 5 additions & 0 deletions crates/cranelift/src/gc/enabled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
},
},
};
Expand Down Expand Up @@ -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]);

Expand Down Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions crates/cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/environ/src/compile/module_environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions crates/environ/src/compile/module_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -453,7 +454,7 @@ where
WasmHeapType::ConcreteStruct(index)
}
wasmparser::CompositeInnerType::Cont(_) => {
panic!("unimplemented continuation types")
WasmHeapType::ConcreteCont(index)
}
}
} else {
Expand All @@ -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();
Expand All @@ -497,7 +499,7 @@ where
WasmHeapType::ConcreteStruct(index)
}
wasmparser::CompositeInnerType::Cont(_) => {
panic!("unimplemented continuation types")
WasmHeapType::ConcreteCont(index)
}
}
} else {
Expand Down
1 change: 1 addition & 0 deletions crates/environ/src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}

Expand Down
113 changes: 111 additions & 2 deletions crates/environ/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,11 @@ pub enum WasmHeapType {
ConcreteFunc(EngineOrModuleTypeIndex),
NoFunc,

// Continuation types.
Cont,
ConcreteCont(EngineOrModuleTypeIndex),
NoCont,

// Internal types.
Any,
Eq,
Expand All @@ -454,6 +459,7 @@ impl From<WasmHeapTopType> for WasmHeapType {
WasmHeapTopType::Extern => Self::Extern,
WasmHeapTopType::Any => Self::Any,
WasmHeapTopType::Func => Self::Func,
WasmHeapTopType::Cont => Self::Cont,
}
}
}
Expand All @@ -465,6 +471,7 @@ impl From<WasmHeapBottomType> for WasmHeapType {
WasmHeapBottomType::NoExtern => Self::NoExtern,
WasmHeapBottomType::None => Self::None,
WasmHeapBottomType::NoFunc => Self::NoFunc,
WasmHeapBottomType::NoCont => Self::NoCont,
}
}
}
Expand All @@ -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"),
Expand All @@ -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(()),
}
}
Expand All @@ -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(()),
}
}
Expand All @@ -526,6 +538,7 @@ impl WasmHeapType {

// All `t <: (ref null func)` are not.
WasmHeapTopType::Func => false,
WasmHeapTopType::Cont => false,
}
}

Expand Down Expand Up @@ -555,6 +568,10 @@ impl WasmHeapType {
WasmHeapTopType::Func
}

WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => {
WasmHeapTopType::Cont
}

WasmHeapType::Any
| WasmHeapType::Eq
| WasmHeapType::I31
Expand Down Expand Up @@ -582,6 +599,10 @@ impl WasmHeapType {
WasmHeapBottomType::NoFunc
}

WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => {
WasmHeapBottomType::NoCont
}

WasmHeapType::Any
| WasmHeapType::Eq
| WasmHeapType::I31
Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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<F, E>(&self, func: &mut F) -> Result<(), E>
where
F: FnMut(EngineOrModuleTypeIndex) -> Result<(), E>,
{
func(self.0)
}

fn trace_mut<F, E>(&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 {
Expand Down Expand Up @@ -935,6 +993,7 @@ pub enum WasmCompositeInnerType {
Array(WasmArrayType),
Func(WasmFuncType),
Struct(WasmStructType),
Cont(WasmContType),
}

impl fmt::Display for WasmCompositeInnerType {
Expand All @@ -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),
}
}
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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),
}
}

Expand All @@ -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),
}
}
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions crates/wasmtime/src/runtime/type_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions crates/wasmtime/src/runtime/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
}

Expand Down
Loading