summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
authorAshley Nelson <nashley@google.com>2022-06-21 20:57:43 -0700
committerGitHub <noreply@github.com>2022-06-21 20:57:43 -0700
commit3b9c2e85fa5d97ba08a95c0c7cce7d041e699cde (patch)
treec01eb86869401931006b6503e47d60b9a44511b0 /src/wasm/wasm-binary.cpp
parent7fa4c0841c31930759fbad2efb8ada3ef0e6f3ef (diff)
downloadbinaryen-3b9c2e85fa5d97ba08a95c0c7cce7d041e699cde.tar.gz
binaryen-3b9c2e85fa5d97ba08a95c0c7cce7d041e699cde.tar.bz2
binaryen-3b9c2e85fa5d97ba08a95c0c7cce7d041e699cde.zip
First class Data Segments (#4733)
* Updating wasm.h/cpp for DataSegments * Updating wasm-binary.h/cpp for DataSegments * Removed link from Memory to DataSegments and updated module-utils, Metrics and wasm-traversal * checking isPassive when copying data segments to know whether to construct the data segment with an offset or not * Removing memory member var from DataSegment class as there is only one memory rn. Updated wasm-validator.cpp * Updated wasm-interpreter * First look at updating Passes * Updated wasm-s-parser * Updated files in src/ir * Updating tools files * Last pass on src files before building * added visitDataSegment * Fixing build errors * Data segments need a name * fixing var name * ran clang-format * Ensuring a name on DataSegment * Ensuring more datasegments have names * Adding explicit name support * Fix fuzzing name * Outputting data name in wasm binary only if explicit * Checking temp dataSegments vector to validateBinary because it's the one with the segments before we processNames * Pass on when data segment names are explicitly set * Ran auto_update_tests.py and check.py, success all around * Removed an errant semi-colon and corrected a counter. Everything still passes * Linting * Fixing processing memory names after parsed from binary * Updating the test from the last fix * Correcting error comment * Impl kripken@ comments * Impl tlively@ comments * Updated tests that remove data print when == 0 * Ran clang format * Impl tlively@ comments * Ran clang-format
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r--src/wasm/wasm-binary.cpp67
1 files changed, 36 insertions, 31 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index c161a623b..b74331aed 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -517,36 +517,36 @@ void WasmBinaryWriter::writeExports() {
}
void WasmBinaryWriter::writeDataCount() {
- if (!wasm->features.hasBulkMemory() || !wasm->memory.segments.size()) {
+ if (!wasm->features.hasBulkMemory() || !wasm->dataSegments.size()) {
return;
}
auto start = startSection(BinaryConsts::Section::DataCount);
- o << U32LEB(wasm->memory.segments.size());
+ o << U32LEB(wasm->dataSegments.size());
finishSection(start);
}
void WasmBinaryWriter::writeDataSegments() {
- if (wasm->memory.segments.size() == 0) {
+ if (wasm->dataSegments.size() == 0) {
return;
}
- if (wasm->memory.segments.size() > WebLimitations::MaxDataSegments) {
+ if (wasm->dataSegments.size() > WebLimitations::MaxDataSegments) {
std::cerr << "Some VMs may not accept this binary because it has a large "
<< "number of data segments. Run the limit-segments pass to "
<< "merge segments.\n";
}
auto start = startSection(BinaryConsts::Section::Data);
- o << U32LEB(wasm->memory.segments.size());
- for (auto& segment : wasm->memory.segments) {
+ o << U32LEB(wasm->dataSegments.size());
+ for (auto& segment : wasm->dataSegments) {
uint32_t flags = 0;
- if (segment.isPassive) {
+ if (segment->isPassive) {
flags |= BinaryConsts::IsPassive;
}
o << U32LEB(flags);
- if (!segment.isPassive) {
- writeExpression(segment.offset);
+ if (!segment->isPassive) {
+ writeExpression(segment->offset);
o << int8_t(BinaryConsts::End);
}
- writeInlineBuffer(segment.data.data(), segment.data.size());
+ writeInlineBuffer(segment->data.data(), segment->data.size());
}
finishSection(start);
}
@@ -919,8 +919,8 @@ void WasmBinaryWriter::writeNames() {
// data segment names
if (wasm->memory.exists) {
Index count = 0;
- for (auto& seg : wasm->memory.segments) {
- if (seg.name.is()) {
+ for (auto& seg : wasm->dataSegments) {
+ if (seg->hasExplicitName) {
count++;
}
}
@@ -929,11 +929,11 @@ void WasmBinaryWriter::writeNames() {
auto substart =
startSubsection(BinaryConsts::UserSections::Subsection::NameData);
o << U32LEB(count);
- for (Index i = 0; i < wasm->memory.segments.size(); i++) {
- auto& seg = wasm->memory.segments[i];
- if (seg.name.is()) {
+ for (Index i = 0; i < wasm->dataSegments.size(); i++) {
+ auto& seg = wasm->dataSegments[i];
+ if (seg->name.is()) {
o << U32LEB(i);
- writeEscapedName(seg.name.str);
+ writeEscapedName(seg->name.str);
}
}
finishSubsection(substart);
@@ -1482,7 +1482,7 @@ void WasmBinaryBuilder::read() {
readDataSegments();
break;
case BinaryConsts::Section::DataCount:
- readDataCount();
+ readDataSegmentCount();
break;
case BinaryConsts::Section::Table:
readTableDeclarations();
@@ -2791,7 +2791,7 @@ Expression* WasmBinaryBuilder::popTypedExpression(Type type) {
}
void WasmBinaryBuilder::validateBinary() {
- if (hasDataCount && wasm.memory.segments.size() != dataCount) {
+ if (hasDataCount && dataSegments.size() != dataCount) {
throwError("Number of segments does not agree with DataCount section");
}
}
@@ -2809,7 +2809,9 @@ void WasmBinaryBuilder::processNames() {
for (auto& segment : elementSegments) {
wasm.addElementSegment(std::move(segment));
}
-
+ for (auto& segment : dataSegments) {
+ wasm.addDataSegment(std::move(segment));
+ }
// now that we have names, apply things
if (startIndex != static_cast<Index>(-1)) {
@@ -2888,8 +2890,8 @@ void WasmBinaryBuilder::processNames() {
wasm.updateMaps();
}
-void WasmBinaryBuilder::readDataCount() {
- BYN_TRACE("== readDataCount\n");
+void WasmBinaryBuilder::readDataSegmentCount() {
+ BYN_TRACE("== readDataSegmentCount\n");
hasDataCount = true;
dataCount = getU32LEB();
}
@@ -2898,26 +2900,27 @@ void WasmBinaryBuilder::readDataSegments() {
BYN_TRACE("== readDataSegments\n");
auto num = getU32LEB();
for (size_t i = 0; i < num; i++) {
- Memory::Segment curr;
+ auto curr = Builder::makeDataSegment();
uint32_t flags = getU32LEB();
if (flags > 2) {
throwError("bad segment flags, must be 0, 1, or 2, not " +
std::to_string(flags));
}
- curr.isPassive = flags & BinaryConsts::IsPassive;
+ curr->setName(Name::fromInt(i), false);
+ curr->isPassive = flags & BinaryConsts::IsPassive;
if (flags & BinaryConsts::HasIndex) {
auto memIndex = getU32LEB();
if (memIndex != 0) {
throwError("nonzero memory index");
}
}
- if (!curr.isPassive) {
- curr.offset = readExpression();
+ if (!curr->isPassive) {
+ curr->offset = readExpression();
}
auto size = getU32LEB();
auto data = getByteView(size);
- curr.data = {data.first, data.second};
- wasm.memory.segments.push_back(std::move(curr));
+ curr->data = {data.first, data.second};
+ dataSegments.push_back(std::move(curr));
}
}
@@ -3254,14 +3257,16 @@ void WasmBinaryBuilder::readNames(size_t payloadLen) {
}
} else if (nameType == BinaryConsts::UserSections::Subsection::NameData) {
auto num = getU32LEB();
+ NameProcessor processor;
for (size_t i = 0; i < num; i++) {
auto index = getU32LEB();
auto rawName = getInlineString();
- if (index < wasm.memory.segments.size()) {
- wasm.memory.segments[i].name = rawName;
+ auto name = processor.process(rawName);
+ if (index < dataSegments.size()) {
+ dataSegments[i]->setExplicitName(name);
} else {
- std::cerr << "warning: memory index out of bounds in name section, "
- "memory subsection: "
+ std::cerr << "warning: data index out of bounds in name section, "
+ "data subsection: "
<< std::string(rawName.str) << " at index "
<< std::to_string(index) << std::endl;
}