diff options
-rw-r--r-- | src/ir/type-updating.cpp | 7 | ||||
-rw-r--r-- | test/lit/passes/gto-mutability.wast | 35 |
2 files changed, 42 insertions, 0 deletions
diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index d3ecf7ad6..cacdc9000 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -100,6 +100,13 @@ void GlobalTypeRewriter::update() { if (type.isRtt()) { return Type(Rtt(type.getRtt().depth, getNew(type.getHeapType()))); } + if (type.isTuple()) { + auto tuple = type.getTuple(); + for (auto& t : tuple.types) { + t = getNew(t); + } + return Type(tuple); + } return type; } diff --git a/test/lit/passes/gto-mutability.wast b/test/lit/passes/gto-mutability.wast index bd657bb90..6cb3575d7 100644 --- a/test/lit/passes/gto-mutability.wast +++ b/test/lit/passes/gto-mutability.wast @@ -10,6 +10,9 @@ ;; CHECK: (type $struct (struct_subtype (field (mut funcref)) (field funcref) (field (mut funcref)) data)) (type $struct (struct (field (mut funcref)) (field (mut funcref)) (field (mut funcref)))) + ;; CHECK: (type $two-params (func_subtype (param (ref $struct) (ref $struct)) func)) + (type $two-params (func (param (ref $struct)) (param (ref $struct)))) + ;; Test that we update tag types properly. ;; CHECK: (type $ref|$struct|_=>_none (func_subtype (param (ref $struct)) func)) @@ -17,6 +20,11 @@ ;; CHECK: (type $none_=>_none (func_subtype func)) + ;; CHECK: (table $0 0 funcref) + (table 0 funcref) + + ;; CHECK: (elem declare func $func-two-params) + ;; CHECK: (tag $tag (param (ref $struct))) (tag $tag (param (ref $struct))) @@ -117,6 +125,33 @@ (ref.null $struct) ) + ;; CHECK: (func $func-two-params (param $x (ref $struct)) (param $y (ref $struct)) + ;; CHECK-NEXT: (local $z (ref null $two-params)) + ;; CHECK-NEXT: (local.set $z + ;; CHECK-NEXT: (ref.func $func-two-params) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $0 (type $two-params) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $func-two-params (param $x (ref $struct)) (param $y (ref $struct)) + ;; This function has two params, which means a tuple type is used for its + ;; signature, which we must also update. To verify the update is correct, + ;; assign it to a local. + (local $z (ref null $two-params)) + (local.set $z + (ref.func $func-two-params) + ) + ;; Also check that a call_indirect still validates after the rewriting. + (call_indirect (type $two-params) + (local.get $x) + (local.get $y) + (i32.const 0) + ) + ) + ;; CHECK: (func $field-keepalive ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get $struct 2 |