Skip to content

Commit c85632b

Browse files
authored
Add nullexnref and noexn types to exception-handling (#1485)
1 parent 3710141 commit c85632b

File tree

17 files changed

+99
-21
lines changed

17 files changed

+99
-21
lines changed

crates/wasm-encoder/src/core/types.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,12 @@ pub enum HeapType {
450450
/// The unboxed `i31` heap type.
451451
I31,
452452

453-
/// The abstract` exception` heap type.
453+
/// The abstract `exception` heap type.
454454
Exn,
455455

456+
/// The abstract `noexn` heap type.
457+
NoExn,
458+
456459
/// A concrete Wasm-defined type at the given index.
457460
Concrete(u32),
458461
}
@@ -471,6 +474,7 @@ impl Encode for HeapType {
471474
HeapType::Array => sink.push(0x6A),
472475
HeapType::I31 => sink.push(0x6C),
473476
HeapType::Exn => sink.push(0x69),
477+
HeapType::NoExn => sink.push(0x74),
474478
// Note that this is encoded as a signed type rather than unsigned
475479
// as it's decoded as an s33
476480
HeapType::Concrete(i) => i64::from(*i).encode(sink),
@@ -496,6 +500,7 @@ impl TryFrom<wasmparser::HeapType> for HeapType {
496500
wasmparser::HeapType::Array => HeapType::Array,
497501
wasmparser::HeapType::I31 => HeapType::I31,
498502
wasmparser::HeapType::Exn => HeapType::Exn,
503+
wasmparser::HeapType::NoExn => HeapType::NoExn,
499504
})
500505
}
501506
}

crates/wasm-mutate/src/module.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ pub fn map_ref_type(ref_ty: wasmparser::RefType) -> Result<RefType> {
9191
wasmparser::HeapType::Array => HeapType::Array,
9292
wasmparser::HeapType::I31 => HeapType::I31,
9393
wasmparser::HeapType::Exn => HeapType::Exn,
94+
wasmparser::HeapType::NoExn => HeapType::NoExn,
9495
wasmparser::HeapType::Concrete(i) => HeapType::Concrete(i.as_module_index().unwrap()),
9596
},
9697
})

crates/wasm-mutate/src/mutators/translate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ pub fn heapty(t: &mut dyn Translator, ty: &wasmparser::HeapType) -> Result<HeapT
212212
wasmparser::HeapType::Array => Ok(HeapType::Array),
213213
wasmparser::HeapType::I31 => Ok(HeapType::I31),
214214
wasmparser::HeapType::Exn => Ok(HeapType::Exn),
215+
wasmparser::HeapType::NoExn => Ok(HeapType::NoExn),
215216
wasmparser::HeapType::Concrete(i) => Ok(HeapType::Concrete(
216217
t.remap(Item::Type, i.as_module_index().unwrap())?,
217218
)),

crates/wasm-smith/src/core.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ impl Module {
496496
matches!(self.ty(b).composite_type, CompositeType::Func(_))
497497
}
498498

499+
(HT::NoExn, HT::Exn) => true,
500+
499501
// Nothing else matches. (Avoid full wildcard matches so that
500502
// adding/modifying variants is easier in the future.)
501503
(HT::Concrete(_), _)
@@ -508,11 +510,9 @@ impl Module {
508510
| (HT::Eq, _)
509511
| (HT::Struct, _)
510512
| (HT::Array, _)
511-
| (HT::I31, _) => false,
512-
513-
// TODO: `exn` probably will be its own type hierarchy and will
514-
// probably get `noexn` as well.
515-
(HT::Exn, _) => false,
513+
| (HT::I31, _)
514+
| (HT::Exn, _)
515+
| (HT::NoExn, _) => false,
516516
}
517517
}
518518

@@ -781,7 +781,7 @@ impl Module {
781781
HT::Extern => {
782782
choices.push(HT::NoExtern);
783783
}
784-
HT::Exn | HT::None | HT::NoExtern | HT::NoFunc => {}
784+
HT::Exn | HT::NoExn | HT::None | HT::NoExtern | HT::NoFunc => {}
785785
}
786786
Ok(*u.choose(&choices)?)
787787
}
@@ -860,6 +860,9 @@ impl Module {
860860
choices.extend(self.func_types.iter().copied().map(HT::Concrete));
861861
choices.push(HT::Func);
862862
}
863+
HT::NoExn => {
864+
choices.push(HT::Exn);
865+
}
863866
HT::Concrete(mut idx) => {
864867
match &self
865868
.types
@@ -1648,6 +1651,7 @@ impl Module {
16481651
wasmparser::HeapType::Array => HeapType::Array,
16491652
wasmparser::HeapType::I31 => HeapType::I31,
16501653
wasmparser::HeapType::Exn => HeapType::Exn,
1654+
wasmparser::HeapType::NoExn => HeapType::NoExn,
16511655
}
16521656
}
16531657

crates/wasmparser/src/readers/core/types.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,8 @@ impl std::fmt::Debug for RefType {
878878
(false, HeapType::Func) => write!(f, "(ref func)"),
879879
(true, HeapType::Exn) => write!(f, "exnref"),
880880
(false, HeapType::Exn) => write!(f, "(ref exn)"),
881+
(true, HeapType::NoExn) => write!(f, "nullexnref"),
882+
(false, HeapType::NoExn) => write!(f, "(ref noexn)"),
881883
(true, HeapType::Concrete(idx)) => write!(f, "(ref null {idx})"),
882884
(false, HeapType::Concrete(idx)) => write!(f, "(ref {idx})"),
883885
}
@@ -928,6 +930,7 @@ impl RefType {
928930
const EXTERN_ABSTYPE: u32 = 0b0011 << 18;
929931
const NOEXTERN_ABSTYPE: u32 = 0b0010 << 18;
930932
const EXN_ABSTYPE: u32 = 0b0001 << 18;
933+
const NOEXN_ABSTYPE: u32 = 0b1110 << 18;
931934
const NONE_ABSTYPE: u32 = 0b0000 << 18;
932935

933936
// The `index` is valid only when `concrete == 1`.
@@ -972,6 +975,10 @@ impl RefType {
972975
/// `exnref`.
973976
pub const EXNREF: Self = RefType::EXN.nullable();
974977

978+
/// A nullable reference to a noexn object aka `(ref null noexn)` aka
979+
/// `nullexnref`.
980+
pub const NULLEXNREF: Self = RefType::NOEXN.nullable();
981+
975982
/// A non-nullable untyped function reference aka `(ref func)`.
976983
pub const FUNC: Self = RefType::from_u32(Self::FUNC_ABSTYPE);
977984

@@ -1005,6 +1012,9 @@ impl RefType {
10051012
/// A non-nullable reference to an exn object aka `(ref exn)`.
10061013
pub const EXN: Self = RefType::from_u32(Self::EXN_ABSTYPE);
10071014

1015+
/// A non-nullable reference to a noexn object aka `(ref noexn)`.
1016+
pub const NOEXN: Self = RefType::from_u32(Self::NOEXN_ABSTYPE);
1017+
10081018
const fn can_represent_type_index(index: u32) -> bool {
10091019
index & Self::INDEX_MASK == index
10101020
}
@@ -1045,6 +1055,7 @@ impl RefType {
10451055
| Self::NOEXTERN_ABSTYPE
10461056
| Self::NONE_ABSTYPE
10471057
| Self::EXN_ABSTYPE
1058+
| Self::NOEXN_ABSTYPE
10481059
)
10491060
);
10501061

@@ -1083,6 +1094,7 @@ impl RefType {
10831094
HeapType::Array => Some(Self::from_u32(nullable32 | Self::ARRAY_ABSTYPE)),
10841095
HeapType::I31 => Some(Self::from_u32(nullable32 | Self::I31_ABSTYPE)),
10851096
HeapType::Exn => Some(Self::from_u32(nullable32 | Self::EXN_ABSTYPE)),
1097+
HeapType::NoExn => Some(Self::from_u32(nullable32 | Self::NOEXN_ABSTYPE)),
10861098
}
10871099
}
10881100

@@ -1179,6 +1191,7 @@ impl RefType {
11791191
Self::ARRAY_ABSTYPE => HeapType::Array,
11801192
Self::I31_ABSTYPE => HeapType::I31,
11811193
Self::EXN_ABSTYPE => HeapType::Exn,
1194+
Self::NOEXN_ABSTYPE => HeapType::NoExn,
11821195
_ => unreachable!(),
11831196
}
11841197
}
@@ -1200,6 +1213,7 @@ impl RefType {
12001213
(true, HeapType::Array) => "arrayref",
12011214
(true, HeapType::I31) => "i31ref",
12021215
(true, HeapType::Exn) => "exnref",
1216+
(true, HeapType::NoExn) => "nullexnref",
12031217
(false, HeapType::Func) => "(ref func)",
12041218
(false, HeapType::Extern) => "(ref extern)",
12051219
(false, HeapType::Concrete(_)) => "(ref $type)",
@@ -1212,6 +1226,7 @@ impl RefType {
12121226
(false, HeapType::Array) => "(ref array)",
12131227
(false, HeapType::I31) => "(ref i31)",
12141228
(false, HeapType::Exn) => "(ref exn)",
1229+
(false, HeapType::NoExn) => "(ref noexn)",
12151230
}
12161231
}
12171232
}
@@ -1297,13 +1312,20 @@ pub enum HeapType {
12971312
///
12981313
/// Introduced in the exception-handling proposal.
12991314
Exn,
1315+
1316+
/// The abstract `noexn` heap type.
1317+
///
1318+
/// The common subtype (a.k.a. bottom) of all exception types.
1319+
///
1320+
/// Introduced in the exception-handling proposal.
1321+
NoExn,
13001322
}
13011323

13021324
impl ValType {
13031325
pub(crate) fn is_valtype_byte(byte: u8) -> bool {
13041326
match byte {
13051327
0x7F | 0x7E | 0x7D | 0x7C | 0x7B | 0x70 | 0x6F | 0x64 | 0x63 | 0x6E | 0x71 | 0x72
1306-
| 0x73 | 0x6D | 0x6B | 0x6A | 0x6C | 0x69 => true,
1328+
| 0x74 | 0x73 | 0x6D | 0x6B | 0x6A | 0x6C | 0x69 => true,
13071329
_ => false,
13081330
}
13091331
}
@@ -1348,8 +1370,8 @@ impl<'a> FromReader<'a> for ValType {
13481370
reader.position += 1;
13491371
Ok(ValType::V128)
13501372
}
1351-
0x70 | 0x6F | 0x64 | 0x63 | 0x6E | 0x71 | 0x72 | 0x73 | 0x6D | 0x6B | 0x6A | 0x6C
1352-
| 0x69 => Ok(ValType::Ref(reader.read()?)),
1373+
0x70 | 0x6F | 0x64 | 0x63 | 0x6E | 0x71 | 0x72 | 0x73 | 0x74 | 0x6D | 0x6B | 0x6A
1374+
| 0x6C | 0x69 => Ok(ValType::Ref(reader.read()?)),
13531375
_ => bail!(reader.original_position(), "invalid value type"),
13541376
}
13551377
}
@@ -1369,6 +1391,7 @@ impl<'a> FromReader<'a> for RefType {
13691391
0x6A => Ok(RefType::ARRAY.nullable()),
13701392
0x6C => Ok(RefType::I31.nullable()),
13711393
0x69 => Ok(RefType::EXN.nullable()),
1394+
0x74 => Ok(RefType::NOEXN.nullable()),
13721395
byte @ (0x63 | 0x64) => {
13731396
let nullable = byte == 0x63;
13741397
let pos = reader.original_position();
@@ -1427,6 +1450,10 @@ impl<'a> FromReader<'a> for HeapType {
14271450
reader.position += 1;
14281451
Ok(HeapType::Exn)
14291452
}
1453+
0x74 => {
1454+
reader.position += 1;
1455+
Ok(HeapType::NoExn)
1456+
}
14301457
_ => {
14311458
let idx = match u32::try_from(reader.read_var_s33()?) {
14321459
Ok(idx) => idx,

crates/wasmparser/src/validator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ impl WasmFeatures {
358358
}
359359

360360
// These types were added in the exception-handling proposal.
361-
(HeapType::Exn, _) => {
361+
(HeapType::Exn | HeapType::NoExn, _) => {
362362
if self.exceptions {
363363
Ok(())
364364
} else {

crates/wasmparser/src/validator/core.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,8 @@ impl Module {
982982
| HeapType::Struct
983983
| HeapType::Array
984984
| HeapType::I31
985-
| HeapType::Exn => return Ok(()),
985+
| HeapType::Exn
986+
| HeapType::NoExn => return Ok(()),
986987
HeapType::Concrete(type_index) => type_index,
987988
};
988989
match type_index {

crates/wasmparser/src/validator/types.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2695,6 +2695,8 @@ impl TypeList {
26952695
matches!(subtype(b_group, b).composite_type, CompositeType::Func(_))
26962696
}
26972697

2698+
(HT::NoExn, HT::Exn) => true,
2699+
26982700
// Nothing else matches. (Avoid full wildcard matches so that
26992701
// adding/modifying variants is easier in the future.)
27002702
(HT::Concrete(_), _)
@@ -2707,11 +2709,9 @@ impl TypeList {
27072709
| (HT::Eq, _)
27082710
| (HT::Struct, _)
27092711
| (HT::Array, _)
2710-
| (HT::I31, _) => false,
2711-
2712-
// TODO: this probably isn't right, this is probably related to some
2713-
// gc type.
2714-
(HT::Exn, _) => false,
2712+
| (HT::I31, _)
2713+
| (HT::Exn, _)
2714+
| (HT::NoExn, _) => false,
27152715
}
27162716
}
27172717

@@ -2749,7 +2749,7 @@ impl TypeList {
27492749
| HeapType::Array
27502750
| HeapType::I31
27512751
| HeapType::None => HeapType::Any,
2752-
HeapType::Exn => HeapType::Exn,
2752+
HeapType::Exn | HeapType::NoExn => HeapType::Exn,
27532753
}
27542754
}
27552755

crates/wasmprinter/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,7 @@ impl Printer {
969969
RefType::STRUCT => self.result.push_str("structref"),
970970
RefType::ARRAY => self.result.push_str("arrayref"),
971971
RefType::EXN => self.result.push_str("exnref"),
972+
RefType::NOEXN => self.result.push_str("nullexnref"),
972973
_ => {
973974
self.result.push_str("(ref null ");
974975
self.print_heaptype(state, ty.heap_type())?;
@@ -996,6 +997,7 @@ impl Printer {
996997
HeapType::Array => self.result.push_str("array"),
997998
HeapType::I31 => self.result.push_str("i31"),
998999
HeapType::Exn => self.result.push_str("exn"),
1000+
HeapType::NoExn => self.result.push_str("noexn"),
9991001
HeapType::Concrete(i) => {
10001002
self.print_idx(&state.core.type_names, i.as_module_index().unwrap())?;
10011003
}

crates/wast/src/component/binary.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ impl From<core::HeapType<'_>> for wasm_encoder::HeapType {
597597
match r {
598598
core::HeapType::Func => Self::Func,
599599
core::HeapType::Extern => Self::Extern,
600-
core::HeapType::Exn => {
600+
core::HeapType::Exn | core::HeapType::NoExn => {
601601
todo!("encoding of exceptions proposal types not yet implemented")
602602
}
603603
core::HeapType::Concrete(Index::Num(i, _)) => Self::Concrete(i),

0 commit comments

Comments
 (0)