diff options
author | Thomas Lively <tlively@google.com> | 2022-10-18 13:54:22 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-18 13:54:22 -0500 |
commit | 8377174c3bb56b58cda054b3210799439004e229 (patch) | |
tree | 0d172db76ef1409b4c2e4134a39e1418dfbb52fc | |
parent | 6bef18672fae68ee4976a7b26f277f6caa32734f (diff) | |
download | binaryen-8377174c3bb56b58cda054b3210799439004e229.tar.gz binaryen-8377174c3bb56b58cda054b3210799439004e229.tar.bz2 binaryen-8377174c3bb56b58cda054b3210799439004e229.zip |
Parse and emit `array.len` without a type annotation (#5151)
Test that we can still parse the old annotated form as well.
-rw-r--r-- | src/passes/Print.cpp | 9 | ||||
-rw-r--r-- | src/wasm-binary.h | 3 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 7 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 11 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 2 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 2 | ||||
-rw-r--r-- | test/heap-types.wast.from-wast | 4 | ||||
-rw-r--r-- | test/heap-types.wast.fromBinary | 2 | ||||
-rw-r--r-- | test/heap-types.wast.fromBinary.noDebugInfo | 2 | ||||
-rw-r--r-- | test/lit/arrays.wast | 34 | ||||
-rw-r--r-- | test/lit/binary/annotated-array-len.test | 18 | ||||
-rw-r--r-- | test/lit/binary/annotated-array-len.test.wasm | bin | 0 -> 36 bytes | |||
-rw-r--r-- | test/lit/passes/gufa-refs.wast | 2 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-gc.wast | 4 | ||||
-rw-r--r-- | test/passes/Oz_fuzz-exec_all-features.txt | 4 |
15 files changed, 68 insertions, 36 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 0f4a314ae..d0f19f78e 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2236,14 +2236,7 @@ struct PrintExpressionContents printMedium(o, "array.set "); TypeNamePrinter(o, wasm).print(curr->ref->type.getHeapType()); } - void visitArrayLen(ArrayLen* curr) { - printMedium(o, "array.len "); - if (curr->ref->type == Type::unreachable) { - TypeNamePrinter(o, wasm).print(HeapType::array); - } else { - TypeNamePrinter(o, wasm).print(curr->ref->type.getHeapType()); - } - } + void visitArrayLen(ArrayLen* curr) { printMedium(o, "array.len"); } void visitArrayCopy(ArrayCopy* curr) { if (printUnreachableOrNullReplacement(curr->srcRef) || printUnreachableOrNullReplacement(curr->destRef)) { diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 709c0c9f9..db123515a 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1111,8 +1111,9 @@ enum ASTNodes { ArrayGetS = 0x14, ArrayGetU = 0x15, ArraySet = 0x16, - ArrayLen = 0x17, + ArrayLenAnnotated = 0x17, ArrayCopy = 0x18, + ArrayLen = 0x19, ArrayInitStatic = 0x1a, ArrayNew = 0x1b, ArrayNewDefault = 0x1c, diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 13c28f151..54c904459 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7111,11 +7111,12 @@ bool WasmBinaryBuilder::maybeVisitArraySet(Expression*& out, uint32_t code) { } bool WasmBinaryBuilder::maybeVisitArrayLen(Expression*& out, uint32_t code) { - if (code != BinaryConsts::ArrayLen) { + if (code == BinaryConsts::ArrayLenAnnotated) { + // Ignore the type annotation and don't bother validating it. + getU32LEB(); + } else if (code != BinaryConsts::ArrayLen) { return false; } - // Ignore the type annotation and don't bother validating it. - getU32LEB(); auto* ref = popNonVoidExpression(); out = Builder(wasm).makeArrayLen(ref); return true; diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 41a0619f9..78ac84f42 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -3027,9 +3027,14 @@ Expression* SExpressionWasmBuilder::makeArraySet(Element& s) { } Expression* SExpressionWasmBuilder::makeArrayLen(Element& s) { - // Ignore the type annotation and don't bother validating it. - parseHeapType(*s[1]); - auto ref = parseExpression(*s[2]); + // There may or may not be a type annotation. + Index i = 1; + try { + parseHeapType(*s[i]); + ++i; + } catch (...) { + } + auto ref = parseExpression(*s[i]); return Builder(wasm).makeArrayLen(ref); } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 7c1c121d5..f30e4be82 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2169,8 +2169,6 @@ void BinaryInstWriter::visitArraySet(ArraySet* curr) { void BinaryInstWriter::visitArrayLen(ArrayLen* curr) { o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::ArrayLen); - // Unused type index. - o << U32LEB(0); } void BinaryInstWriter::visitArrayCopy(ArrayCopy* curr) { diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 5c6400ce5..983c80d90 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -2213,7 +2213,7 @@ BinaryenFeatureAll: 126975 (i32.const 42) ) (drop - (array.len $[mut:i8] + (array.len (global.get $i8Array-global) ) ) diff --git a/test/heap-types.wast.from-wast b/test/heap-types.wast.from-wast index 4994857e2..dc41451cd 100644 --- a/test/heap-types.wast.from-wast +++ b/test/heap-types.wast.from-wast @@ -150,7 +150,7 @@ ) ) (drop - (array.len $vector + (array.len (local.get $x) ) ) @@ -383,7 +383,7 @@ ) (func $unreachables-array-6 (drop - (array.len array + (array.len (unreachable) ) ) diff --git a/test/heap-types.wast.fromBinary b/test/heap-types.wast.fromBinary index dc55e1e8f..f16e07c7f 100644 --- a/test/heap-types.wast.fromBinary +++ b/test/heap-types.wast.fromBinary @@ -148,7 +148,7 @@ ) ) (drop - (array.len $vector + (array.len (local.get $x) ) ) diff --git a/test/heap-types.wast.fromBinary.noDebugInfo b/test/heap-types.wast.fromBinary.noDebugInfo index 9c5194750..53c3b0bd6 100644 --- a/test/heap-types.wast.fromBinary.noDebugInfo +++ b/test/heap-types.wast.fromBinary.noDebugInfo @@ -148,7 +148,7 @@ ) ) (drop - (array.len $[mut:f64] + (array.len (local.get $0) ) ) diff --git a/test/lit/arrays.wast b/test/lit/arrays.wast index b79ca1844..31aead1cd 100644 --- a/test/lit/arrays.wast +++ b/test/lit/arrays.wast @@ -11,25 +11,25 @@ (module (type $byte-array (array (mut i8))) + ;; CHECK: (type $arrayref_=>_i32 (func (param arrayref) (result i32))) + ;; CHECK: (type $ref|array|_=>_i32 (func (param (ref array)) (result i32))) ;; CHECK: (type $nullref_=>_i32 (func (param nullref) (result i32))) - ;; CHECK: (type $arrayref_=>_i32 (func (param arrayref) (result i32))) - ;; CHECK: (func $len (param $a (ref array)) (result i32) - ;; CHECK-NEXT: (array.len array + ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (local.get $a) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; ROUNDTRIP: (type $arrayref_=>_i32 (func (param arrayref) (result i32))) + ;; ROUNDTRIP: (type $ref|array|_=>_i32 (func (param (ref array)) (result i32))) ;; ROUNDTRIP: (type $nullref_=>_i32 (func (param nullref) (result i32))) - ;; ROUNDTRIP: (type $arrayref_=>_i32 (func (param arrayref) (result i32))) - ;; ROUNDTRIP: (func $len (param $a (ref array)) (result i32) - ;; ROUNDTRIP-NEXT: (array.len array + ;; ROUNDTRIP-NEXT: (array.len ;; ROUNDTRIP-NEXT: (local.get $a) ;; ROUNDTRIP-NEXT: ) ;; ROUNDTRIP-NEXT: ) @@ -41,12 +41,12 @@ ) ;; CHECK: (func $impossible-len (param $none nullref) (result i32) - ;; CHECK-NEXT: (array.len none + ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (local.get $none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; ROUNDTRIP: (func $impossible-len (param $none nullref) (result i32) - ;; ROUNDTRIP-NEXT: (array.len none + ;; ROUNDTRIP-NEXT: (array.len ;; ROUNDTRIP-NEXT: (local.get $none) ;; ROUNDTRIP-NEXT: ) ;; ROUNDTRIP-NEXT: ) @@ -57,7 +57,7 @@ ) ;; CHECK: (func $unreachable-len (param $a arrayref) (result i32) - ;; CHECK-NEXT: (array.len array + ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -69,4 +69,20 @@ (unreachable) ) ) + + ;; CHECK: (func $unannotated-len (param $a arrayref) (result i32) + ;; CHECK-NEXT: (array.len + ;; CHECK-NEXT: (local.get $a) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; ROUNDTRIP: (func $unannotated-len (param $a arrayref) (result i32) + ;; ROUNDTRIP-NEXT: (array.len + ;; ROUNDTRIP-NEXT: (local.get $a) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: ) + (func $unannotated-len (param $a arrayref) (result i32) + (array.len + (local.get $a) + ) + ) ) diff --git a/test/lit/binary/annotated-array-len.test b/test/lit/binary/annotated-array-len.test new file mode 100644 index 000000000..a8eb08fe7 --- /dev/null +++ b/test/lit/binary/annotated-array-len.test @@ -0,0 +1,18 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; Test the we can properly parse the annotated array.len format that we no +;; longer emit. + +;; RUN: wasm-dis %s.wasm -all --nominal | filecheck %s + +;; CHECK: (type $none_=>_i32 (func_subtype (result i32) func)) + +;; CHECK: (type $[mut:i8] (array_subtype (mut i8) data)) + +;; CHECK: (func $0 (type $none_=>_i32) (result i32) +;; CHECK-NEXT: (array.len +;; CHECK-NEXT: (array.new_default $[mut:i8] +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) diff --git a/test/lit/binary/annotated-array-len.test.wasm b/test/lit/binary/annotated-array-len.test.wasm Binary files differnew file mode 100644 index 000000000..b199f58de --- /dev/null +++ b/test/lit/binary/annotated-array-len.test.wasm diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index 09de96fca..ec58e10a0 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -4150,7 +4150,7 @@ ;; CHECK: (func $arrays (type $ref|$B|_=>_none) (param $B (ref $B)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (array.len $B + ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (array.init_static $B ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index c0d106250..fb50d103f 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -766,7 +766,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (array.len $array + ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -801,7 +801,7 @@ ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (array.len $array + ;; NOMNL-NEXT: (array.len ;; NOMNL-NEXT: (local.get $y) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt index e19110848..a38193d08 100644 --- a/test/passes/Oz_fuzz-exec_all-features.txt +++ b/test/passes/Oz_fuzz-exec_all-features.txt @@ -123,7 +123,7 @@ (func $1 (; has Stack IR ;) (local $0 (ref $bytes)) (call $log - (array.len $bytes + (array.len (local.tee $0 (array.new $bytes (i32.const 42) @@ -319,7 +319,7 @@ (func $24 (; has Stack IR ;) (local $0 (ref $bytes)) (call $log - (array.len $bytes + (array.len (local.tee $0 (array.init_static $bytes (i32.const 42) |