summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-03-09 12:30:36 -0800
committerGitHub <noreply@github.com>2021-03-09 12:30:36 -0800
commita1187630835e747ba7609296ab0ecb85df0b07b2 (patch)
treecb4a15e120785c8fc7f2172bbdd240e0ddc724ec /src
parenta1d3e63f89e9d13daabf626033a66fe5b8a8bce1 (diff)
downloadbinaryen-a1187630835e747ba7609296ab0ecb85df0b07b2.tar.gz
binaryen-a1187630835e747ba7609296ab0ecb85df0b07b2.tar.bz2
binaryen-a1187630835e747ba7609296ab0ecb85df0b07b2.zip
[Wasm GC] Properly handle "typeindex" in the binary format (#3663)
We handled them as S63 instead of U32. That should be fine, as all U32 values fit in S63. But it is not strictly correct. The signed encoding may use an additional byte which is unnecessary, and there is an actual correctness issue where a U32 may be interpreted as a large negative S63 (because it sign extends a final bit that happens to be 1). May help #3656 but that testcase still does not pass even with this.
Diffstat (limited to 'src')
-rw-r--r--src/wasm-binary.h11
-rw-r--r--src/wasm/wasm-binary.cpp38
-rw-r--r--src/wasm/wasm-stack.cpp18
3 files changed, 42 insertions, 25 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 8ca07e7d2..326c37bf0 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1250,7 +1250,15 @@ public:
Module* getModule() { return wasm; }
void writeType(Type type);
+
+ // Writes an arbitrary heap type, which may be indexed or one of the
+ // basic types like funcref.
void writeHeapType(HeapType type);
+ // Writes an indexed heap type. Note that this is encoded differently than a
+ // general heap type because it does not allow negative values for basic heap
+ // types.
+ void writeIndexedHeapType(HeapType type);
+
void writeField(const Field& field);
private:
@@ -1344,8 +1352,9 @@ public:
Type getType();
// Get a type given the initial S32LEB has already been read, and is provided.
Type getType(int initial);
-
HeapType getHeapType();
+ HeapType getIndexedHeapType();
+
Type getConcreteType();
Name getInlineString();
void verifyInt8(int8_t x);
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index dacb6edbb..2eb8bdcde 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1185,7 +1185,7 @@ void WasmBinaryWriter::writeType(Type type) {
} else {
o << S32LEB(BinaryConsts::EncodedType::rtt);
}
- writeHeapType(rtt.heapType);
+ writeIndexedHeapType(rtt.heapType);
return;
}
int ret = 0;
@@ -1267,6 +1267,10 @@ void WasmBinaryWriter::writeHeapType(HeapType type) {
o << S64LEB(ret); // TODO: Actually s33
}
+void WasmBinaryWriter::writeIndexedHeapType(HeapType type) {
+ o << U32LEB(getTypeIndex(type));
+}
+
void WasmBinaryWriter::writeField(const Field& field) {
if (field.type == Type::i32 && field.packedType != Field::not_packed) {
if (field.packedType == Field::i8) {
@@ -1676,6 +1680,14 @@ HeapType WasmBinaryBuilder::getHeapType() {
WASM_UNREACHABLE("unexpected type");
}
+HeapType WasmBinaryBuilder::getIndexedHeapType() {
+ auto index = getU32LEB();
+ if (index >= types.size()) {
+ throwError("invalid heap type index: " + std::to_string(index));
+ }
+ return types[index];
+}
+
Type WasmBinaryBuilder::getConcreteType() {
auto type = getType();
if (!type.isConcrete()) {
@@ -1789,11 +1801,7 @@ void WasmBinaryBuilder::readTypes() {
case BinaryConsts::EncodedType::rtt: {
auto depth = typeCode == BinaryConsts::EncodedType::rtt ? Rtt::NoDepth
: getU32LEB();
- int64_t htCode = getS64LEB(); // TODO: Actually s33
- HeapType ht;
- if (getBasicHeapType(htCode, ht)) {
- return Type(Rtt(depth, ht));
- }
+ auto htCode = getU32LEB();
if (size_t(htCode) >= numTypes) {
throwError("invalid type index: " + std::to_string(htCode));
}
@@ -6359,7 +6367,7 @@ bool WasmBinaryBuilder::maybeVisitRttCanon(Expression*& out, uint32_t code) {
if (code != BinaryConsts::RttCanon) {
return false;
}
- auto heapType = getHeapType();
+ auto heapType = getIndexedHeapType();
out = Builder(wasm).makeRttCanon(heapType);
return true;
}
@@ -6368,7 +6376,7 @@ bool WasmBinaryBuilder::maybeVisitRttSub(Expression*& out, uint32_t code) {
if (code != BinaryConsts::RttSub) {
return false;
}
- auto targetHeapType = getHeapType();
+ auto targetHeapType = getIndexedHeapType();
auto* parent = popNonVoidExpression();
out = Builder(wasm).makeRttSub(targetHeapType, parent);
return true;
@@ -6379,7 +6387,7 @@ bool WasmBinaryBuilder::maybeVisitStructNew(Expression*& out, uint32_t code) {
code != BinaryConsts::StructNewDefaultWithRtt) {
return false;
}
- auto heapType = getHeapType();
+ auto heapType = getIndexedHeapType();
auto* rtt = popNonVoidExpression();
validateHeapTypeUsingChild(rtt, heapType);
std::vector<Expression*> operands;
@@ -6411,7 +6419,7 @@ bool WasmBinaryBuilder::maybeVisitStructGet(Expression*& out, uint32_t code) {
default:
return false;
}
- auto heapType = getHeapType();
+ auto heapType = getIndexedHeapType();
curr->index = getU32LEB();
curr->ref = popNonVoidExpression();
validateHeapTypeUsingChild(curr->ref, heapType);
@@ -6425,7 +6433,7 @@ bool WasmBinaryBuilder::maybeVisitStructSet(Expression*& out, uint32_t code) {
return false;
}
auto* curr = allocator.alloc<StructSet>();
- auto heapType = getHeapType();
+ auto heapType = getIndexedHeapType();
curr->index = getU32LEB();
curr->value = popNonVoidExpression();
curr->ref = popNonVoidExpression();
@@ -6440,7 +6448,7 @@ bool WasmBinaryBuilder::maybeVisitArrayNew(Expression*& out, uint32_t code) {
code != BinaryConsts::ArrayNewDefaultWithRtt) {
return false;
}
- auto heapType = getHeapType();
+ auto heapType = getIndexedHeapType();
auto* rtt = popNonVoidExpression();
validateHeapTypeUsingChild(rtt, heapType);
auto* size = popNonVoidExpression();
@@ -6464,7 +6472,7 @@ bool WasmBinaryBuilder::maybeVisitArrayGet(Expression*& out, uint32_t code) {
default:
return false;
}
- auto heapType = getHeapType();
+ auto heapType = getIndexedHeapType();
auto* index = popNonVoidExpression();
auto* ref = popNonVoidExpression();
validateHeapTypeUsingChild(ref, heapType);
@@ -6476,7 +6484,7 @@ bool WasmBinaryBuilder::maybeVisitArraySet(Expression*& out, uint32_t code) {
if (code != BinaryConsts::ArraySet) {
return false;
}
- auto heapType = getHeapType();
+ auto heapType = getIndexedHeapType();
auto* value = popNonVoidExpression();
auto* index = popNonVoidExpression();
auto* ref = popNonVoidExpression();
@@ -6489,7 +6497,7 @@ bool WasmBinaryBuilder::maybeVisitArrayLen(Expression*& out, uint32_t code) {
if (code != BinaryConsts::ArrayLen) {
return false;
}
- auto heapType = getHeapType();
+ auto heapType = getIndexedHeapType();
auto* ref = popNonVoidExpression();
validateHeapTypeUsingChild(ref, heapType);
out = Builder(wasm).makeArrayLen(ref);
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 0c7448c58..2c8bc051f 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2030,12 +2030,12 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) {
void BinaryInstWriter::visitRttCanon(RttCanon* curr) {
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RttCanon);
- parent.writeHeapType(curr->type.getRtt().heapType);
+ parent.writeIndexedHeapType(curr->type.getRtt().heapType);
}
void BinaryInstWriter::visitRttSub(RttSub* curr) {
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RttSub);
- parent.writeHeapType(curr->type.getRtt().heapType);
+ parent.writeIndexedHeapType(curr->type.getRtt().heapType);
}
void BinaryInstWriter::visitStructNew(StructNew* curr) {
@@ -2045,7 +2045,7 @@ void BinaryInstWriter::visitStructNew(StructNew* curr) {
} else {
o << U32LEB(BinaryConsts::StructNewWithRtt);
}
- parent.writeHeapType(curr->rtt->type.getHeapType());
+ parent.writeIndexedHeapType(curr->rtt->type.getHeapType());
}
void BinaryInstWriter::visitStructGet(StructGet* curr) {
@@ -2060,13 +2060,13 @@ void BinaryInstWriter::visitStructGet(StructGet* curr) {
op = BinaryConsts::StructGetU;
}
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(op);
- parent.writeHeapType(heapType);
+ parent.writeIndexedHeapType(heapType);
o << U32LEB(curr->index);
}
void BinaryInstWriter::visitStructSet(StructSet* curr) {
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::StructSet);
- parent.writeHeapType(curr->ref->type.getHeapType());
+ parent.writeIndexedHeapType(curr->ref->type.getHeapType());
o << U32LEB(curr->index);
}
@@ -2077,7 +2077,7 @@ void BinaryInstWriter::visitArrayNew(ArrayNew* curr) {
} else {
o << U32LEB(BinaryConsts::ArrayNewWithRtt);
}
- parent.writeHeapType(curr->rtt->type.getHeapType());
+ parent.writeIndexedHeapType(curr->rtt->type.getHeapType());
}
void BinaryInstWriter::visitArrayGet(ArrayGet* curr) {
@@ -2092,17 +2092,17 @@ void BinaryInstWriter::visitArrayGet(ArrayGet* curr) {
op = BinaryConsts::ArrayGetU;
}
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(op);
- parent.writeHeapType(heapType);
+ parent.writeIndexedHeapType(heapType);
}
void BinaryInstWriter::visitArraySet(ArraySet* curr) {
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::ArraySet);
- parent.writeHeapType(curr->ref->type.getHeapType());
+ parent.writeIndexedHeapType(curr->ref->type.getHeapType());
}
void BinaryInstWriter::visitArrayLen(ArrayLen* curr) {
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::ArrayLen);
- parent.writeHeapType(curr->ref->type.getHeapType());
+ parent.writeIndexedHeapType(curr->ref->type.getHeapType());
}
void BinaryInstWriter::visitRefAs(RefAs* curr) {