Skip to content

Commit 692490b

Browse files
authored
Continuation types (#10255)
1 parent e81164f commit 692490b

File tree

14 files changed

+152
-5
lines changed

14 files changed

+152
-5
lines changed

crates/cranelift/src/func_environ.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,8 @@ impl<'a, 'func, 'module_env> Call<'a, 'func, 'module_env> {
14581458
return CheckIndirectCallTypeSignature::StaticTrap;
14591459
}
14601460

1461+
WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => todo!(), // FIXME: #10248 stack switching support.
1462+
14611463
// Engine-indexed types don't show up until runtime and it's a Wasm
14621464
// validation error to perform a call through a non-function table,
14631465
// so these cases are dynamically not reachable.
@@ -1701,6 +1703,7 @@ impl<'module_environment> TargetEnvironment for FuncEnvironment<'module_environm
17011703
let needs_stack_map = match wasm_ty.top() {
17021704
WasmHeapTopType::Extern | WasmHeapTopType::Any => true,
17031705
WasmHeapTopType::Func => false,
1706+
WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support.
17041707
};
17051708
(ty, needs_stack_map)
17061709
}
@@ -1816,6 +1819,9 @@ impl FuncEnvironment<'_> {
18161819
WasmHeapTopType::Func => {
18171820
Ok(self.get_or_init_func_ref_table_elem(builder, table_index, index, false))
18181821
}
1822+
1823+
// Continuation types.
1824+
WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support.
18191825
}
18201826
}
18211827

@@ -1862,6 +1868,9 @@ impl FuncEnvironment<'_> {
18621868
.store(flags, value_with_init_bit, elem_addr, 0);
18631869
Ok(())
18641870
}
1871+
1872+
// Continuation types.
1873+
WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support.
18651874
}
18661875
}
18671876

@@ -2213,6 +2222,7 @@ impl FuncEnvironment<'_> {
22132222
WasmHeapTopType::Func => pos.ins().iconst(self.pointer_type(), 0),
22142223
// NB: null GC references don't need to be in stack maps.
22152224
WasmHeapTopType::Any | WasmHeapTopType::Extern => pos.ins().iconst(types::I32, 0),
2225+
WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support.
22162226
})
22172227
}
22182228

crates/cranelift/src/gc/enabled.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ fn read_field_at_addr(
148148
.call(get_interned_func_ref, &[vmctx, func_ref_id, expected_ty]);
149149
builder.func.dfg.first_result(call_inst)
150150
}
151+
WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support.
151152
},
152153
},
153154
};
@@ -1059,6 +1060,8 @@ pub fn translate_ref_test(
10591060

10601061
func_env.is_subtype(builder, actual_shared_ty, expected_shared_ty)
10611062
}
1063+
1064+
WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => todo!(), // FIXME: #10248 stack switching support.
10621065
};
10631066
builder.ins().jump(continue_block, &[result]);
10641067

@@ -1391,6 +1394,8 @@ impl FuncEnvironment<'_> {
13911394
WasmHeapType::Func | WasmHeapType::ConcreteFunc(_) | WasmHeapType::NoFunc => {
13921395
unreachable!()
13931396
}
1397+
1398+
WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => todo!(), // FIXME: #10248 stack switching support.
13941399
};
13951400

13961401
match (ty.nullable, might_be_i31) {

crates/cranelift/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ fn reference_type(wasm_ht: WasmHeapType, pointer_type: ir::Type) -> ir::Type {
202202
match wasm_ht.top() {
203203
WasmHeapTopType::Func => pointer_type,
204204
WasmHeapTopType::Any | WasmHeapTopType::Extern => ir::types::I32,
205+
WasmHeapTopType::Cont => todo!(), // FIXME: #10248 stack switching support.
205206
}
206207
}
207208

crates/environ/src/compile/module_environ.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,7 @@ impl ModuleTranslation<'_> {
12201220
// initializer won't trap so we could continue processing
12211221
// segments, but that's left as a future optimization if
12221222
// necessary.
1223-
WasmHeapTopType::Any | WasmHeapTopType::Extern => break,
1223+
WasmHeapTopType::Any | WasmHeapTopType::Extern | WasmHeapTopType::Cont => break,
12241224
}
12251225

12261226
// Function indices can be optimized here, but fully general

crates/environ/src/compile/module_types.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ where
438438
WasmCompositeInnerType::Array(_) => WasmHeapType::ConcreteArray(index),
439439
WasmCompositeInnerType::Func(_) => WasmHeapType::ConcreteFunc(index),
440440
WasmCompositeInnerType::Struct(_) => WasmHeapType::ConcreteStruct(index),
441+
WasmCompositeInnerType::Cont(_) => WasmHeapType::ConcreteCont(index),
441442
}
442443
} else if let Some((wasmparser_types, _)) = self.rec_group_context.as_ref() {
443444
let wasmparser_ty = &wasmparser_types[id].composite_type;
@@ -453,7 +454,7 @@ where
453454
WasmHeapType::ConcreteStruct(index)
454455
}
455456
wasmparser::CompositeInnerType::Cont(_) => {
456-
panic!("unimplemented continuation types")
457+
WasmHeapType::ConcreteCont(index)
457458
}
458459
}
459460
} else {
@@ -477,6 +478,7 @@ where
477478
WasmCompositeInnerType::Array(_) => WasmHeapType::ConcreteArray(index),
478479
WasmCompositeInnerType::Func(_) => WasmHeapType::ConcreteFunc(index),
479480
WasmCompositeInnerType::Struct(_) => WasmHeapType::ConcreteStruct(index),
481+
WasmCompositeInnerType::Cont(_) => WasmHeapType::ConcreteCont(index),
480482
}
481483
} else if let Some((parser_types, rec_group)) = self.rec_group_context.as_ref() {
482484
let rec_group_index = interned.index() - self.types.types.len_types();
@@ -497,7 +499,7 @@ where
497499
WasmHeapType::ConcreteStruct(index)
498500
}
499501
wasmparser::CompositeInnerType::Cont(_) => {
500-
panic!("unimplemented continuation types")
502+
WasmHeapType::ConcreteCont(index)
501503
}
502504
}
503505
} else {

crates/environ/src/gc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ pub trait GcTypeLayouts {
162162
WasmCompositeInnerType::Array(ty) => Some(self.array_layout(ty).into()),
163163
WasmCompositeInnerType::Struct(ty) => Some(self.struct_layout(ty).into()),
164164
WasmCompositeInnerType::Func(_) => None,
165+
WasmCompositeInnerType::Cont(_) => None,
165166
}
166167
}
167168

crates/environ/src/types.rs

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,11 @@ pub enum WasmHeapType {
436436
ConcreteFunc(EngineOrModuleTypeIndex),
437437
NoFunc,
438438

439+
// Continuation types.
440+
Cont,
441+
ConcreteCont(EngineOrModuleTypeIndex),
442+
NoCont,
443+
439444
// Internal types.
440445
Any,
441446
Eq,
@@ -454,6 +459,7 @@ impl From<WasmHeapTopType> for WasmHeapType {
454459
WasmHeapTopType::Extern => Self::Extern,
455460
WasmHeapTopType::Any => Self::Any,
456461
WasmHeapTopType::Func => Self::Func,
462+
WasmHeapTopType::Cont => Self::Cont,
457463
}
458464
}
459465
}
@@ -465,6 +471,7 @@ impl From<WasmHeapBottomType> for WasmHeapType {
465471
WasmHeapBottomType::NoExtern => Self::NoExtern,
466472
WasmHeapBottomType::None => Self::None,
467473
WasmHeapBottomType::NoFunc => Self::NoFunc,
474+
WasmHeapBottomType::NoCont => Self::NoCont,
468475
}
469476
}
470477
}
@@ -477,6 +484,9 @@ impl fmt::Display for WasmHeapType {
477484
Self::Func => write!(f, "func"),
478485
Self::ConcreteFunc(i) => write!(f, "func {i}"),
479486
Self::NoFunc => write!(f, "nofunc"),
487+
Self::Cont => write!(f, "cont"),
488+
Self::ConcreteCont(i) => write!(f, "cont {i}"),
489+
Self::NoCont => write!(f, "nocont"),
480490
Self::Any => write!(f, "any"),
481491
Self::Eq => write!(f, "eq"),
482492
Self::I31 => write!(f, "i31"),
@@ -498,6 +508,7 @@ impl TypeTrace for WasmHeapType {
498508
Self::ConcreteArray(i) => func(i),
499509
Self::ConcreteFunc(i) => func(i),
500510
Self::ConcreteStruct(i) => func(i),
511+
Self::ConcreteCont(i) => func(i),
501512
_ => Ok(()),
502513
}
503514
}
@@ -510,6 +521,7 @@ impl TypeTrace for WasmHeapType {
510521
Self::ConcreteArray(i) => func(i),
511522
Self::ConcreteFunc(i) => func(i),
512523
Self::ConcreteStruct(i) => func(i),
524+
Self::ConcreteCont(i) => func(i),
513525
_ => Ok(()),
514526
}
515527
}
@@ -526,6 +538,7 @@ impl WasmHeapType {
526538

527539
// All `t <: (ref null func)` are not.
528540
WasmHeapTopType::Func => false,
541+
WasmHeapTopType::Cont => false,
529542
}
530543
}
531544

@@ -555,6 +568,10 @@ impl WasmHeapType {
555568
WasmHeapTopType::Func
556569
}
557570

571+
WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => {
572+
WasmHeapTopType::Cont
573+
}
574+
558575
WasmHeapType::Any
559576
| WasmHeapType::Eq
560577
| WasmHeapType::I31
@@ -582,6 +599,10 @@ impl WasmHeapType {
582599
WasmHeapBottomType::NoFunc
583600
}
584601

602+
WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => {
603+
WasmHeapBottomType::NoCont
604+
}
605+
585606
WasmHeapType::Any
586607
| WasmHeapType::Eq
587608
| WasmHeapType::I31
@@ -603,6 +624,8 @@ pub enum WasmHeapTopType {
603624
Any,
604625
/// The common supertype of all function references.
605626
Func,
627+
/// The common supertype of all continuation references.
628+
Cont,
606629
}
607630

608631
/// A bottom heap type.
@@ -614,6 +637,8 @@ pub enum WasmHeapBottomType {
614637
None,
615638
/// The common subtype of all function references.
616639
NoFunc,
640+
/// The common subtype of all continuation references.
641+
NoCont,
617642
}
618643

619644
/// WebAssembly function type -- equivalent of `wasmparser`'s FuncType.
@@ -761,6 +786,39 @@ impl WasmFuncType {
761786
}
762787
}
763788

789+
/// WebAssembly continuation type -- equivalent of `wasmparser`'s ContType.
790+
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
791+
pub struct WasmContType(EngineOrModuleTypeIndex);
792+
793+
impl fmt::Display for WasmContType {
794+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
795+
write!(f, "(cont {})", self.0)
796+
}
797+
}
798+
799+
impl WasmContType {
800+
/// Constructs a new continuation type.
801+
pub fn new(idx: EngineOrModuleTypeIndex) -> Self {
802+
WasmContType(idx)
803+
}
804+
}
805+
806+
impl TypeTrace for WasmContType {
807+
fn trace<F, E>(&self, func: &mut F) -> Result<(), E>
808+
where
809+
F: FnMut(EngineOrModuleTypeIndex) -> Result<(), E>,
810+
{
811+
func(self.0)
812+
}
813+
814+
fn trace_mut<F, E>(&mut self, func: &mut F) -> Result<(), E>
815+
where
816+
F: FnMut(&mut EngineOrModuleTypeIndex) -> Result<(), E>,
817+
{
818+
func(&mut self.0)
819+
}
820+
}
821+
764822
/// Represents storage types introduced in the GC spec for array and struct fields.
765823
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
766824
pub enum WasmStorageType {
@@ -935,6 +993,7 @@ pub enum WasmCompositeInnerType {
935993
Array(WasmArrayType),
936994
Func(WasmFuncType),
937995
Struct(WasmStructType),
996+
Cont(WasmContType),
938997
}
939998

940999
impl fmt::Display for WasmCompositeInnerType {
@@ -943,6 +1002,7 @@ impl fmt::Display for WasmCompositeInnerType {
9431002
Self::Array(ty) => fmt::Display::fmt(ty, f),
9441003
Self::Func(ty) => fmt::Display::fmt(ty, f),
9451004
Self::Struct(ty) => fmt::Display::fmt(ty, f),
1005+
Self::Cont(ty) => fmt::Display::fmt(ty, f),
9461006
}
9471007
}
9481008
}
@@ -1002,6 +1062,24 @@ impl WasmCompositeInnerType {
10021062
pub fn unwrap_struct(&self) -> &WasmStructType {
10031063
self.as_struct().unwrap()
10041064
}
1065+
1066+
#[inline]
1067+
pub fn is_cont(&self) -> bool {
1068+
matches!(self, Self::Cont(_))
1069+
}
1070+
1071+
#[inline]
1072+
pub fn as_cont(&self) -> Option<&WasmContType> {
1073+
match self {
1074+
Self::Cont(f) => Some(f),
1075+
_ => None,
1076+
}
1077+
}
1078+
1079+
#[inline]
1080+
pub fn unwrap_cont(&self) -> &WasmContType {
1081+
self.as_cont().unwrap()
1082+
}
10051083
}
10061084

10071085
impl TypeTrace for WasmCompositeType {
@@ -1013,6 +1091,7 @@ impl TypeTrace for WasmCompositeType {
10131091
WasmCompositeInnerType::Array(a) => a.trace(func),
10141092
WasmCompositeInnerType::Func(f) => f.trace(func),
10151093
WasmCompositeInnerType::Struct(a) => a.trace(func),
1094+
WasmCompositeInnerType::Cont(c) => c.trace(func),
10161095
}
10171096
}
10181097

@@ -1024,6 +1103,7 @@ impl TypeTrace for WasmCompositeType {
10241103
WasmCompositeInnerType::Array(a) => a.trace_mut(func),
10251104
WasmCompositeInnerType::Func(f) => f.trace_mut(func),
10261105
WasmCompositeInnerType::Struct(a) => a.trace_mut(func),
1106+
WasmCompositeInnerType::Cont(c) => c.trace_mut(func),
10271107
}
10281108
}
10291109
}
@@ -1123,6 +1203,26 @@ impl WasmSubType {
11231203
assert!(!self.composite_type.shared);
11241204
self.composite_type.inner.unwrap_struct()
11251205
}
1206+
1207+
#[inline]
1208+
pub fn is_cont(&self) -> bool {
1209+
self.composite_type.inner.is_cont() && !self.composite_type.shared
1210+
}
1211+
1212+
#[inline]
1213+
pub fn as_cont(&self) -> Option<&WasmContType> {
1214+
if self.composite_type.shared {
1215+
None
1216+
} else {
1217+
self.composite_type.inner.as_cont()
1218+
}
1219+
}
1220+
1221+
#[inline]
1222+
pub fn unwrap_cont(&self) -> &WasmContType {
1223+
assert!(!self.composite_type.shared);
1224+
self.composite_type.inner.unwrap_cont()
1225+
}
11261226
}
11271227

11281228
impl TypeTrace for WasmSubType {
@@ -2018,8 +2118,8 @@ pub trait TypeConvert {
20182118
wasmparser::CompositeInnerType::Struct(s) => {
20192119
WasmCompositeInnerType::Struct(self.convert_struct_type(s))
20202120
}
2021-
wasmparser::CompositeInnerType::Cont(_) => {
2022-
unimplemented!("continuation types")
2121+
wasmparser::CompositeInnerType::Cont(c) => {
2122+
WasmCompositeInnerType::Cont(self.convert_cont_type(c))
20232123
}
20242124
};
20252125
WasmCompositeType {
@@ -2028,6 +2128,15 @@ pub trait TypeConvert {
20282128
}
20292129
}
20302130

2131+
/// Converts a wasmparser continuation type to a wasmtime type
2132+
fn convert_cont_type(&self, ty: &wasmparser::ContType) -> WasmContType {
2133+
if let WasmHeapType::ConcreteFunc(sigidx) = self.lookup_heap_type(ty.0.unpack()) {
2134+
WasmContType::new(sigidx)
2135+
} else {
2136+
panic!("Failed to extract signature index for continuation type.")
2137+
}
2138+
}
2139+
20312140
fn convert_struct_type(&self, ty: &wasmparser::StructType) -> WasmStructType {
20322141
WasmStructType {
20332142
fields: ty

crates/wasmtime/src/runtime/type_registry.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,7 @@ impl TypeRegistryInner {
851851
.struct_layout(s)
852852
.into(),
853853
),
854+
wasmtime_environ::WasmCompositeInnerType::Cont(_) => todo!(), // FIXME: #10248 stack switching support.
854855
};
855856

856857
// Add the type to our slab.

crates/wasmtime/src/runtime/types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,8 @@ impl HeapType {
10961096
| WasmHeapType::ConcreteStruct(EngineOrModuleTypeIndex::RecGroup(_)) => {
10971097
panic!("HeapType::from_wasm_type on non-canonicalized-for-runtime-usage heap type")
10981098
}
1099+
1100+
WasmHeapType::Cont | WasmHeapType::ConcreteCont(_) | WasmHeapType::NoCont => todo!(), // FIXME: #10248 stack switching support.
10991101
}
11001102
}
11011103

0 commit comments

Comments
 (0)