diff options
author | Alon Zakai <azakai@google.com> | 2020-12-10 15:25:23 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-10 15:25:23 -0800 |
commit | c93da3de39a4592abc6cddbed30b5c7074069a24 (patch) | |
tree | 265bcd421a97a21d58493f65eb29f252bf3a6001 /src/wasm/wasm-s-parser.cpp | |
parent | 57a9e77add02dc1d874fdbfee2c61cae8c0eefa1 (diff) | |
download | binaryen-c93da3de39a4592abc6cddbed30b5c7074069a24.tar.gz binaryen-c93da3de39a4592abc6cddbed30b5c7074069a24.tar.bz2 binaryen-c93da3de39a4592abc6cddbed30b5c7074069a24.zip |
[GC] Add Array operations (#3436)
array.new/get/set/len - pretty straightforward after structs and all the
infrastructure for them.
Also fixes validation of the unnecessary heapType param in the
text and binary formats in structs as well as arrays.
Fixes printing of packed types in type names, which emitted i32
for them. That broke when we emitted the same name for an array
of i8 and i32 as in the new testing here.
Also fix a bug in Field::operator< which was wrong for packed
types; again, this was easy to notice with the new testing.
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 80 |
1 files changed, 47 insertions, 33 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 3bb54f0c8..b9f321b14 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2126,11 +2126,7 @@ Expression* SExpressionWasmBuilder::makeRttSub(Element& s) { Expression* SExpressionWasmBuilder::makeStructNew(Element& s, bool default_) { auto heapType = parseHeapType(*s[1]); auto* rtt = parseExpression(*s[2]); - if (rtt->type != Type::unreachable) { - if (!rtt->type.isRtt() || rtt->type.getHeapType() != heapType) { - throw ParseException("bad struct.new heap type", s.line, s.col); - } - } + validateHeapTypeUsingChild(rtt, heapType, s); auto numOperands = s.size() - 3; if (default_ && numOperands > 0) { throw ParseException( @@ -2161,54 +2157,57 @@ Index SExpressionWasmBuilder::getStructIndex(const HeapType& type, Element& s) { } Expression* SExpressionWasmBuilder::makeStructGet(Element& s, bool signed_) { - auto structType = parseHeapType(*s[1]); - auto index = getStructIndex(structType, *s[2]); - auto type = structType.getStruct().fields[index].type; + auto heapType = parseHeapType(*s[1]); + auto index = getStructIndex(heapType, *s[2]); + auto type = heapType.getStruct().fields[index].type; auto ref = parseExpression(*s[3]); + validateHeapTypeUsingChild(ref, heapType, s); return Builder(wasm).makeStructGet(index, ref, type, signed_); } Expression* SExpressionWasmBuilder::makeStructSet(Element& s) { - auto structType = parseHeapType(*s[1]); - auto index = getStructIndex(structType, *s[2]); + auto heapType = parseHeapType(*s[1]); + auto index = getStructIndex(heapType, *s[2]); auto ref = parseExpression(*s[3]); + validateHeapTypeUsingChild(ref, heapType, s); auto value = parseExpression(*s[4]); return Builder(wasm).makeStructSet(index, ref, value); } Expression* SExpressionWasmBuilder::makeArrayNew(Element& s, bool default_) { - auto ret = allocator.alloc<ArrayNew>(); - WASM_UNREACHABLE("TODO (gc): array.new"); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeArrayGet(Element& s) { - auto ret = allocator.alloc<ArrayGet>(); - WASM_UNREACHABLE("TODO (gc): array.get"); - ret->finalize(); - return ret; + auto heapType = parseHeapType(*s[1]); + auto* rtt = parseExpression(*s[2]); + validateHeapTypeUsingChild(rtt, heapType, s); + auto* size = parseExpression(*s[3]); + Expression* init = nullptr; + if (!default_) { + init = parseExpression(*s[4]); + } + return Builder(wasm).makeArrayNew(rtt, size, init); } Expression* SExpressionWasmBuilder::makeArrayGet(Element& s, bool signed_) { - auto ret = allocator.alloc<ArrayGet>(); - WASM_UNREACHABLE("TODO (gc): array.get_s/u"); - ret->finalize(); - return ret; + auto heapType = parseHeapType(*s[1]); + auto ref = parseExpression(*s[2]); + validateHeapTypeUsingChild(ref, heapType, s); + auto index = parseExpression(*s[3]); + return Builder(wasm).makeArrayGet(ref, index, signed_); } Expression* SExpressionWasmBuilder::makeArraySet(Element& s) { - auto ret = allocator.alloc<ArraySet>(); - WASM_UNREACHABLE("TODO (gc): array.set"); - ret->finalize(); - return ret; + auto heapType = parseHeapType(*s[1]); + auto ref = parseExpression(*s[2]); + validateHeapTypeUsingChild(ref, heapType, s); + auto index = parseExpression(*s[3]); + auto value = parseExpression(*s[4]); + return Builder(wasm).makeArraySet(ref, index, value); } Expression* SExpressionWasmBuilder::makeArrayLen(Element& s) { - auto ret = allocator.alloc<ArrayLen>(); - WASM_UNREACHABLE("TODO (gc): array.len"); - ret->finalize(); - return ret; + auto heapType = parseHeapType(*s[1]); + auto ref = parseExpression(*s[2]); + validateHeapTypeUsingChild(ref, heapType, s); + return Builder(wasm).makeArrayLen(ref); } // converts an s-expression string representing binary data into an output @@ -2969,4 +2968,19 @@ void SExpressionWasmBuilder::parseEvent(Element& s, bool preParseImport) { wasm.addEvent(event.release()); } +void SExpressionWasmBuilder::validateHeapTypeUsingChild(Expression* child, + HeapType heapType, + Element& s) { + if (child->type == Type::unreachable) { + return; + } + if ((!child->type.isRef() && !child->type.isRtt()) || + child->type.getHeapType() != heapType) { + throw ParseException("bad heap type: expected " + heapType.toString() + + " but found " + child->type.toString(), + s.line, + s.col); + } +} + } // namespace wasm |