diff options
author | Thomas Lively <tlively@google.com> | 2024-09-19 17:08:17 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-19 17:08:17 -0700 |
commit | 480f5ba352a9f89afe72779c81f8a16fd3c8ba4a (patch) | |
tree | 55eae60ae748233aa244a7afda693ca6b1927455 /src | |
parent | 2711d4fe4b4514ea146e8810959a8f170c932591 (diff) | |
download | binaryen-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.cpp | 5 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 24 |
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)); } } |