summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r--src/wasm-interpreter.h65
1 files changed, 60 insertions, 5 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index b38272acd..86d868ac8 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1618,6 +1618,13 @@ public:
truncateForPacking(value.getSingleValue(), field);
return Flow();
}
+
+ // Arbitrary deterministic limit on size. If we need to allocate a Literals
+ // vector that takes around 1-2GB of memory then we are likely to hit memory
+ // limits on 32-bit machines, and in particular on wasm32 VMs that do not
+ // have 4GB support, so give up there.
+ static const Index ArrayLimit = (1 << 30) / sizeof(Literal);
+
Flow visitArrayNew(ArrayNew* curr) {
NOTE_ENTER("ArrayNew");
auto rtt = this->visit(curr->rtt);
@@ -1630,11 +1637,7 @@ public:
}
const auto& element = curr->rtt->type.getHeapType().getArray().element;
Index num = size.getSingleValue().geti32();
- // Arbitrary deterministic limit on size. If we need to allocate a Literals
- // vector that takes around 1-2GB of memory then we are likely to hit memory
- // limits on 32-bit machines, and in particular on wasm32 VMs that do not
- // have 4GB support, so give up there.
- if (num >= (1 << 30) / sizeof(Literal)) {
+ if (num >= ArrayLimit) {
hostLimit("allocation failure");
}
Literals data(num);
@@ -1715,6 +1718,58 @@ public:
}
return Literal(int32_t(data->values.size()));
}
+ Flow visitArrayCopy(ArrayCopy* curr) {
+ NOTE_ENTER("ArrayCopy");
+ Flow destRef = this->visit(curr->destRef);
+ if (destRef.breaking()) {
+ return destRef;
+ }
+ Flow destIndex = this->visit(curr->destIndex);
+ if (destIndex.breaking()) {
+ return destIndex;
+ }
+ Flow srcRef = this->visit(curr->srcRef);
+ if (srcRef.breaking()) {
+ return srcRef;
+ }
+ Flow srcIndex = this->visit(curr->srcIndex);
+ if (srcIndex.breaking()) {
+ return srcIndex;
+ }
+ Flow length = this->visit(curr->length);
+ if (length.breaking()) {
+ return length;
+ }
+ auto destData = destRef.getSingleValue().getGCData();
+ if (!destData) {
+ trap("null ref");
+ }
+ auto srcData = srcRef.getSingleValue().getGCData();
+ if (!srcData) {
+ trap("null ref");
+ }
+ size_t destVal = destIndex.getSingleValue().getUnsigned();
+ size_t srcVal = srcIndex.getSingleValue().getUnsigned();
+ size_t lengthVal = length.getSingleValue().getUnsigned();
+ if (lengthVal >= ArrayLimit) {
+ hostLimit("allocation failure");
+ }
+ std::vector<Literal> copied;
+ copied.resize(lengthVal);
+ for (size_t i = 0; i < lengthVal; i++) {
+ if (srcVal + i >= srcData->values.size()) {
+ trap("oob");
+ }
+ copied[i] = srcData->values[srcVal + i];
+ }
+ for (size_t i = 0; i < lengthVal; i++) {
+ if (destVal + i >= destData->values.size()) {
+ trap("oob");
+ }
+ destData->values[destVal + i] = copied[i];
+ }
+ return Flow();
+ }
Flow visitRefAs(RefAs* curr) {
NOTE_ENTER("RefAs");
Flow flow = visit(curr->value);