summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-09-19 17:08:17 -0700
committerGitHub <noreply@github.com>2024-09-19 17:08:17 -0700
commit480f5ba352a9f89afe72779c81f8a16fd3c8ba4a (patch)
tree55eae60ae748233aa244a7afda693ca6b1927455 /src
parent2711d4fe4b4514ea146e8810959a8f170c932591 (diff)
downloadbinaryen-480f5ba352a9f89afe72779c81f8a16fd3c8ba4a.tar.gz
binaryen-480f5ba352a9f89afe72779c81f8a16fd3c8ba4a.tar.bz2
binaryen-480f5ba352a9f89afe72779c81f8a16fd3c8ba4a.zip
[NFC] Eagerly create segments when parsing datacount (#6958)
The purpose of the datacount section is to pre-declare how many data segments there will be so that engines can allocate space for them and not have to back patch subsequent instructions in the code section that refer to them. Once we use IRBuilder in the binary parser, we will have to have the data segments available by the time we parse instructions that use them, so eagerly construct the data segments when parsing the datacount section.
Diffstat (limited to 'src')
-rw-r--r--src/passes/Print.cpp5
-rw-r--r--src/wasm/wasm-binary.cpp24
2 files changed, 26 insertions, 3 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index d49bc2974..427bff329 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -3238,6 +3238,11 @@ void PrintSExpression::visitMemory(Memory* curr) {
}
void PrintSExpression::visitDataSegment(DataSegment* curr) {
+ if (!curr->isPassive && !curr->offset) {
+ // This data segment must have been created from the datacount section but
+ // not parsed yet. Skip it.
+ return;
+ }
doIndent(o, indent);
o << '(';
printMajor(o, "data ");
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index d999141fd..cb9ea3731 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -3273,18 +3273,37 @@ void WasmBinaryReader::processNames() {
void WasmBinaryReader::readDataSegmentCount() {
hasDataCount = true;
dataCount = getU32LEB();
+ // Eagerly create the data segments so they are available during parsing of
+ // the code section.
+ for (size_t i = 0; i < dataCount; ++i) {
+ auto curr = Builder::makeDataSegment();
+ curr->setName(Name::fromInt(i), false);
+ wasm.addDataSegment(std::move(curr));
+ }
}
void WasmBinaryReader::readDataSegments() {
auto num = getU32LEB();
+ if (hasDataCount) {
+ if (num != dataCount) {
+ throwError("data count and data sections disagree on size");
+ }
+ } else {
+ // We haven't already created the data segments, so create them now.
+ for (size_t i = 0; i < num; ++i) {
+ auto curr = Builder::makeDataSegment();
+ curr->setName(Name::fromInt(i), false);
+ wasm.addDataSegment(std::move(curr));
+ }
+ }
+ assert(wasm.dataSegments.size() == num);
for (size_t i = 0; i < num; i++) {
- auto curr = Builder::makeDataSegment();
+ auto& curr = wasm.dataSegments[i];
uint32_t flags = getU32LEB();
if (flags > 2) {
throwError("bad segment flags, must be 0, 1, or 2, not " +
std::to_string(flags));
}
- curr->setName(Name::fromInt(i), false);
curr->isPassive = flags & BinaryConsts::IsPassive;
if (curr->isPassive) {
curr->memory = Name();
@@ -3300,7 +3319,6 @@ void WasmBinaryReader::readDataSegments() {
auto size = getU32LEB();
auto data = getByteView(size);
curr->data = {data.begin(), data.end()};
- wasm.addDataSegment(std::move(curr));
}
}