diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index a8a01841fd6..766409347e6 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -1161,11 +1161,12 @@ struct InfoCollector curr->ref, curr->index, curr->value, MemoryOrder::Unordered); visitArraySet(set); } - template void visitArrayInit(ArrayInit* curr) { + + void handleArrayWrite(Expression* ref) { // Check for both unreachability and a bottom type. In either case we have // no work to do, and would error on an assertion below in finding the array // type. - auto field = GCTypeUtils::getField(curr->ref->type); + auto field = GCTypeUtils::getField(ref->type); if (!field) { return; } @@ -1179,12 +1180,14 @@ struct InfoCollector Builder builder(*getModule()); auto* get = builder.makeLocalGet(-1, valueType); addRoot(get); - auto* set = - builder.makeArraySet(curr->ref, curr->index, get, MemoryOrder::Unordered); + // The index does not matter, as we do not track array indexes yet TODO + Expression* index = builder.makeNop(); + auto* set = builder.makeArraySet(ref, index, get, MemoryOrder::Unordered); visitArraySet(set); } - void visitArrayInitData(ArrayInitData* curr) { visitArrayInit(curr); } - void visitArrayInitElem(ArrayInitElem* curr) { visitArrayInit(curr); } + + void visitArrayInitData(ArrayInitData* curr) { handleArrayWrite(curr->ref); } + void visitArrayInitElem(ArrayInitElem* curr) { handleArrayWrite(curr->ref); } void visitArrayRMW(ArrayRMW* curr) { if (curr->ref->type == Type::unreachable) { return; @@ -1219,6 +1222,7 @@ struct InfoCollector } void visitStringEncode(StringEncode* curr) { // TODO: optimize when possible + handleArrayWrite(curr->array); addRoot(curr); } void visitStringConcat(StringConcat* curr) { diff --git a/test/lit/passes/gufa-closed-open.wast b/test/lit/passes/gufa-closed-open.wast index c87c811df84..df6d4b05eb8 100644 --- a/test/lit/passes/gufa-closed-open.wast +++ b/test/lit/passes/gufa-closed-open.wast @@ -167,3 +167,85 @@ ) ) +;; Write to an array using string.encode. +(module + ;; OPEND: (type $array (array (mut i16))) + ;; CLOSE: (type $array (array (mut i16))) + (type $array (array (mut i16))) + + ;; OPEND: (type $1 (func)) + + ;; OPEND: (type $2 (func (result i32))) + + ;; OPEND: (global $global (ref $array) (array.new_default $array + ;; OPEND-NEXT: (i32.const 42) + ;; OPEND-NEXT: )) + ;; CLOSE: (type $1 (func)) + + ;; CLOSE: (type $2 (func (result i32))) + + ;; CLOSE: (global $global (ref $array) (array.new_default $array + ;; CLOSE-NEXT: (i32.const 42) + ;; CLOSE-NEXT: )) + (global $global (ref $array) (array.new_default $array + (i32.const 42) + )) + + ;; OPEND: (export "encode" (func $encode)) + + ;; OPEND: (export "read" (func $read)) + + ;; OPEND: (func $encode (type $1) + ;; OPEND-NEXT: (drop + ;; OPEND-NEXT: (string.encode_wtf16_array + ;; OPEND-NEXT: (string.const "hello") + ;; OPEND-NEXT: (global.get $global) + ;; OPEND-NEXT: (i32.const 0) + ;; OPEND-NEXT: ) + ;; OPEND-NEXT: ) + ;; OPEND-NEXT: ) + ;; CLOSE: (export "encode" (func $encode)) + + ;; CLOSE: (export "read" (func $read)) + + ;; CLOSE: (func $encode (type $1) + ;; CLOSE-NEXT: (drop + ;; CLOSE-NEXT: (string.encode_wtf16_array + ;; CLOSE-NEXT: (string.const "hello") + ;; CLOSE-NEXT: (global.get $global) + ;; CLOSE-NEXT: (i32.const 0) + ;; CLOSE-NEXT: ) + ;; CLOSE-NEXT: ) + ;; CLOSE-NEXT: ) + (func $encode (export "encode") + (drop + (string.encode_wtf16_array + (string.const "hello") + (global.get $global) + (i32.const 0) + ) + ) + ) + + ;; OPEND: (func $read (type $2) (result i32) + ;; OPEND-NEXT: (array.get_s $array + ;; OPEND-NEXT: (global.get $global) + ;; OPEND-NEXT: (i32.const 0) + ;; OPEND-NEXT: ) + ;; OPEND-NEXT: ) + ;; CLOSE: (func $read (type $2) (result i32) + ;; CLOSE-NEXT: (array.get_s $array + ;; CLOSE-NEXT: (global.get $global) + ;; CLOSE-NEXT: (i32.const 0) + ;; CLOSE-NEXT: ) + ;; CLOSE-NEXT: ) + (func $read (export "read") (result i32) + ;; We could infer what the value is here, since there is only one write. TODO + ;; Meanwhile, we should not infer a wrong value, even in closed world. + (array.get_s $array + (global.get $global) + (i32.const 0) + ) + ) +) +