summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/wasm-validator.cpp3
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.txt2
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.wast2
-rw-r--r--test/spec/ref_cast.wast88
-rw-r--r--test/spec/struct.wast9
5 files changed, 102 insertions, 2 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index a057f34b9..c7423ad6d 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -2261,6 +2261,9 @@ void FunctionValidator::visitRttSub(RttSub* curr) {
curr,
"rtt.canon has a depth of 1 over the parent");
}
+ shouldBeTrue(HeapType::isSubType(rtt.heapType, parentRtt.heapType),
+ curr,
+ "rtt.sub parent must be a supertype");
}
}
diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt
index 54b204163..37b3f32fa 100644
--- a/test/passes/Oz_fuzz-exec_all-features.txt
+++ b/test/passes/Oz_fuzz-exec_all-features.txt
@@ -35,7 +35,7 @@
(module
(type $struct (struct (field (mut i32))))
(type $void_func (func))
- (type $extendedstruct (struct (field i32) (field f64)))
+ (type $extendedstruct (struct (field (mut i32)) (field f64)))
(type $bytes (array (mut i8)))
(type $i32_=>_none (func (param i32)))
(type $anyref_=>_none (func (param anyref)))
diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast
index 8320a50a1..f6bb23f69 100644
--- a/test/passes/Oz_fuzz-exec_all-features.wast
+++ b/test/passes/Oz_fuzz-exec_all-features.wast
@@ -1,6 +1,6 @@
(module
(type $struct (struct (mut i32)))
- (type $extendedstruct (struct i32 f64))
+ (type $extendedstruct (struct (mut i32) f64))
(type $bytes (array (mut i8)))
(type $void_func (func))
diff --git a/test/spec/ref_cast.wast b/test/spec/ref_cast.wast
new file mode 100644
index 000000000..aa51ef23f
--- /dev/null
+++ b/test/spec/ref_cast.wast
@@ -0,0 +1,88 @@
+(module
+ (type $t0 (struct))
+ (type $t1 (struct (field i32)))
+ (type $t1' (struct (field i32)))
+ (type $t2 (struct (field i32) (field i32)))
+ (type $t2' (struct (field i32) (field i32)))
+ (type $t3 (struct (field i32) (field i32)))
+
+ (global $t0 (rtt $t0) (rtt.canon $t0))
+ (global $t0' (rtt $t0) (rtt.canon $t0))
+ (global $t1 (rtt $t1) (rtt.sub $t1 (global.get $t0)))
+ (global $t1' (rtt $t1') (rtt.sub $t1' (global.get $t0)))
+ (global $t2 (rtt $t2) (rtt.sub $t2 (global.get $t1)))
+ (global $t2' (rtt $t2') (rtt.sub $t2' (global.get $t1')))
+ (global $t3 (rtt $t3) (rtt.sub $t3 (global.get $t0)))
+ (global $t4 (rtt $t3) (rtt.sub $t3 (rtt.sub $t0 (global.get $t0))))
+
+ (global $tab.0 (mut dataref) (ref.null data))
+ (global $tab.1 (mut dataref) (ref.null data))
+ (global $tab.2 (mut dataref) (ref.null data))
+ (global $tab.3 (mut dataref) (ref.null data))
+ (global $tab.4 (mut dataref) (ref.null data))
+ (global $tab.10 (mut dataref) (ref.null data))
+ (global $tab.11 (mut dataref) (ref.null data))
+ (global $tab.12 (mut dataref) (ref.null data))
+
+ (func $init
+ (global.set $tab.0 (struct.new_default_with_rtt $t0 (global.get $t0)))
+ (global.set $tab.10 (struct.new_default_with_rtt $t0 (global.get $t0')))
+ (global.set $tab.1 (struct.new_default_with_rtt $t1 (global.get $t1)))
+ (global.set $tab.11 (struct.new_default_with_rtt $t1' (global.get $t1')))
+ (global.set $tab.2 (struct.new_default_with_rtt $t2 (global.get $t2)))
+ (global.set $tab.12 (struct.new_default_with_rtt $t2' (global.get $t2')))
+ (global.set $tab.3 (struct.new_default_with_rtt $t3 (global.get $t3)))
+ (global.set $tab.4 (struct.new_default_with_rtt $t3 (global.get $t4)))
+ )
+
+ (func (export "test-sub")
+ (call $init)
+
+ (drop (ref.cast (ref.null data) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.0) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.1) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.2) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.3) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.4) (global.get $t0)))
+
+ (drop (ref.cast (ref.null data) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.1) (global.get $t1)))
+ (drop (ref.cast (global.get $tab.2) (global.get $t1)))
+
+ (drop (ref.cast (ref.null data) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.2) (global.get $t2)))
+
+ (drop (ref.cast (ref.null data) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.3) (global.get $t3)))
+
+ (drop (ref.cast (ref.null data) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.4) (global.get $t4)))
+ )
+
+ (func (export "test-canon")
+ (call $init)
+
+ (drop (ref.cast (global.get $tab.0) (global.get $t0')))
+ (drop (ref.cast (global.get $tab.1) (global.get $t0')))
+ (drop (ref.cast (global.get $tab.2) (global.get $t0')))
+ (drop (ref.cast (global.get $tab.3) (global.get $t0')))
+ (drop (ref.cast (global.get $tab.4) (global.get $t0')))
+
+ (drop (ref.cast (global.get $tab.10) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.11) (global.get $t0)))
+ (drop (ref.cast (global.get $tab.12) (global.get $t0)))
+
+ (drop (ref.cast (global.get $tab.1) (global.get $t1')))
+ (drop (ref.cast (global.get $tab.2) (global.get $t1')))
+
+ (drop (ref.cast (global.get $tab.11) (global.get $t1)))
+ (drop (ref.cast (global.get $tab.12) (global.get $t1)))
+
+ (drop (ref.cast (global.get $tab.2) (global.get $t2')))
+
+ (drop (ref.cast (global.get $tab.12) (global.get $t2)))
+ )
+)
+
+(invoke "test-sub")
+(invoke "test-canon")
diff --git a/test/spec/struct.wast b/test/spec/struct.wast
index 994b025d1..20f5a0d63 100644
--- a/test/spec/struct.wast
+++ b/test/spec/struct.wast
@@ -96,3 +96,12 @@
)
"type mismatch"
)
+
+(assert_invalid
+ (module
+ (type $A (struct (field i32)))
+ (type $B (struct (field i64)))
+ (global $glob (rtt $A) (rtt.sub $A (rtt.canon $B)))
+ )
+ "invalid rtt"
+)