Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions scripts/test/fuzzing.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
'cont_many_unhandled.wast',
'cont_export.wast',
'cont_export_throw.wast',
'type-merging-cont.wast',
# TODO: fix split_wast() on tricky escaping situations like a string ending
# in \\" (the " is not escaped - there is an escaped \ before it)
'string-lifting-section.wast',
Expand Down
14 changes: 12 additions & 2 deletions src/passes/TypeMerging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ bool shapeEq(HeapType a, HeapType b);
bool shapeEq(const Struct& a, const Struct& b);
bool shapeEq(Array a, Array b);
bool shapeEq(Signature a, Signature b);
bool shapeEq(Continuation a, Continuation b);
bool shapeEq(Field a, Field b);
bool shapeEq(Type a, Type b);
bool shapeEq(const Tuple& a, const Tuple& b);
Expand All @@ -232,6 +233,7 @@ size_t shapeHash(HeapType a);
size_t shapeHash(const Struct& a);
size_t shapeHash(Array a);
size_t shapeHash(Signature a);
size_t shapeHash(Continuation a);
size_t shapeHash(Field a);
size_t shapeHash(Type a);
size_t shapeHash(const Tuple& a);
Expand Down Expand Up @@ -690,7 +692,10 @@ bool shapeEq(HeapType a, HeapType b) {
}
break;
case HeapTypeKind::Cont:
WASM_UNREACHABLE("TODO: cont");
if (!shapeEq(a.getContinuation(), b.getContinuation())) {
return false;
}
break;
case HeapTypeKind::Basic:
WASM_UNREACHABLE("unexpected kind");
}
Expand Down Expand Up @@ -719,7 +724,8 @@ size_t shapeHash(HeapType a) {
hash_combine(digest, shapeHash(type.getArray()));
continue;
case HeapTypeKind::Cont:
WASM_UNREACHABLE("TODO: cont");
hash_combine(digest, shapeHash(type.getContinuation()));
continue;
case HeapTypeKind::Basic:
continue;
}
Expand Down Expand Up @@ -762,6 +768,10 @@ size_t shapeHash(Signature a) {
return digest;
}

bool shapeEq(Continuation a, Continuation b) { return shapeEq(a.type, b.type); }

size_t shapeHash(Continuation a) { return shapeHash(a.type); }

bool shapeEq(Field a, Field b) {
return a.packedType == b.packedType && a.mutable_ == b.mutable_ &&
shapeEq(a.type, b.type);
Expand Down
50 changes: 50 additions & 0 deletions test/lit/passes/type-merging-cont.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.

;; RUN: foreach %s %t wasm-opt -all --closed-world --preserve-type-order \
;; RUN: --type-merging --remove-unused-types -S -o - | filecheck %s

;; $A1 and $A2 can be merged, and $B1/$B2, as they have identical continuation
;; fields. But $A*/B* cannot be merged, as the continuations differ.

(module
;; CHECK: (rec
;; CHECK-NEXT: (type $f (func))
(type $f (func))
;; CHECK: (type $f_0 (func))

;; CHECK: (type $k (cont $f_0))
(type $k (cont $f))

(type $f-i32 (func (result i32)))
;; CHECK: (type $f-i32_0 (func (result i32)))

;; CHECK: (type $k-i32 (cont $f-i32_0))
(type $k-i32 (cont $f-i32))

(rec
;; CHECK: (type $A1 (struct (field (ref $k))))
(type $A1 (struct (ref $k)))
;; CHECK: (type $A2 (struct (field (ref $k-i32))))
(type $A2 (struct (ref $k-i32)))
(type $B1 (struct (ref $k)))
Comment thread
kripken marked this conversation as resolved.
Outdated
(type $B2 (struct (ref $k-i32)))
)

;; CHECK: (func $test (type $f)
;; CHECK-NEXT: (local $k (ref $k))
;; CHECK-NEXT: (local $k-i32 (ref $k-i32))
;; CHECK-NEXT: (local $a1 (ref $A1))
;; CHECK-NEXT: (local $a2 (ref $A2))
;; CHECK-NEXT: (local $b1 (ref $A1))
;; CHECK-NEXT: (local $b2 (ref $A2))
;; CHECK-NEXT: )
(func $test
(local $k (ref $k))
(local $k-i32 (ref $k-i32))
(local $a1 (ref $A1))
(local $a2 (ref $A2))
(local $b1 (ref $B1))
(local $b2 (ref $B2))
)
)

Loading