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.h62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 8f7418719..9599d81cd 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1700,6 +1700,7 @@ public:
return Literal(std::make_shared<GCData>(curr->type.getHeapType(), data),
curr->type.getHeapType());
}
+ Flow visitArrayNewSeg(ArrayNewSeg* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitArrayInit(ArrayInit* curr) {
NOTE_ENTER("ArrayInit");
Index num = curr->values.size();
@@ -2187,6 +2188,10 @@ public:
NOTE_ENTER("SIMDLoadStoreLane");
return Flow(NONCONSTANT_FLOW);
}
+ Flow visitArrayNewSeg(ArrayNewSeg* curr) {
+ NOTE_ENTER("ArrayNewSeg");
+ return Flow(NONCONSTANT_FLOW);
+ }
Flow visitPop(Pop* curr) {
NOTE_ENTER("Pop");
return Flow(NONCONSTANT_FLOW);
@@ -3494,6 +3499,63 @@ public:
}
return {};
}
+ Flow visitArrayNewSeg(ArrayNewSeg* curr) {
+ NOTE_ENTER("ArrayNewSeg");
+ auto offsetFlow = self()->visit(curr->offset);
+ if (offsetFlow.breaking()) {
+ return offsetFlow;
+ }
+ auto sizeFlow = self()->visit(curr->size);
+ if (sizeFlow.breaking()) {
+ return sizeFlow;
+ }
+
+ auto offset = offsetFlow.getSingleValue().geti32();
+ auto size = sizeFlow.getSingleValue().geti32();
+
+ auto heapType = curr->type.getHeapType();
+ const auto& element = heapType.getArray().element;
+ auto elemType = heapType.getArray().element.type;
+
+ Literals contents;
+ contents.reserve(size);
+
+ switch (curr->op) {
+ case NewData: {
+ assert(curr->segment < wasm.dataSegments.size());
+ assert(elemType.isNumber());
+ const auto& seg = *wasm.dataSegments[curr->segment];
+ auto elemBytes = element.getByteSize();
+ auto end = (uint64_t)offset + size * elemBytes;
+ if ((size != 0ull && droppedSegments.count(curr->segment)) ||
+ end > seg.data.size()) {
+ trap("out of bounds segment access in array.new_data");
+ }
+ for (Index i = offset; i < end; i += elemBytes) {
+ auto addr = (void*)&seg.data[i];
+ contents.push_back(Literal::makeFromMemory(addr, element));
+ }
+ break;
+ }
+ case NewElem: {
+ assert(curr->segment < wasm.elementSegments.size());
+ const auto& seg = *wasm.elementSegments[curr->segment];
+ auto end = (uint64_t)offset + size;
+ // TODO: Handle dropped element segments once we support those.
+ if (end > seg.data.size()) {
+ trap("out of bounds segment access in array.new_elem");
+ }
+ for (Index i = offset; i < end; ++i) {
+ auto val = self()->visit(seg.data[i]).getSingleValue();
+ contents.push_back(val);
+ }
+ break;
+ }
+ default:
+ WASM_UNREACHABLE("unexpected op");
+ }
+ return Literal(std::make_shared<GCData>(heapType, contents), heapType);
+ }
Flow visitTry(Try* curr) {
NOTE_ENTER("Try");
try {