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 | |
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.
-rw-r--r-- | src/passes/Print.cpp | 5 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 24 | ||||
-rw-r--r-- | test/lit/binary/bad-datacount.test | 9 | ||||
-rwxr-xr-x | test/lit/binary/bad-datacount.test.wasm (renamed from test/unit/input/bulkmem_bad_datacount.wasm) | bin | 177 -> 177 bytes | |||
-rw-r--r-- | test/unit/test_datacount.py | 15 |
5 files changed, 35 insertions, 18 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)); } } diff --git a/test/lit/binary/bad-datacount.test b/test/lit/binary/bad-datacount.test new file mode 100644 index 000000000..27e0c72a3 --- /dev/null +++ b/test/lit/binary/bad-datacount.test @@ -0,0 +1,9 @@ +RUN: not wasm-opt --debug %s.wasm 2>&1 | filecheck %s + +;; Check that we get the expected error. + +;; CHECK: data count and data sections disagree on size + +;; Check that we print out the module rather than hitting an assertion error. + +;; CHECK: (module diff --git a/test/unit/input/bulkmem_bad_datacount.wasm b/test/lit/binary/bad-datacount.test.wasm Binary files differindex e7b6e4bb7..e7b6e4bb7 100755 --- a/test/unit/input/bulkmem_bad_datacount.wasm +++ b/test/lit/binary/bad-datacount.test.wasm diff --git a/test/unit/test_datacount.py b/test/unit/test_datacount.py deleted file mode 100644 index b996865a5..000000000 --- a/test/unit/test_datacount.py +++ /dev/null @@ -1,15 +0,0 @@ -from scripts.test import shared -from . import utils - - -class DataCountTest(utils.BinaryenTestCase): - def test_datacount(self): - self.roundtrip('bulkmem_data.wasm') - - def test_bad_datacount(self): - path = self.input_path('bulkmem_bad_datacount.wasm') - p = shared.run_process(shared.WASM_OPT + ['-g', '-o', '-', path], - check=False, capture_output=True) - self.assertNotEqual(p.returncode, 0) - self.assertIn('Number of segments does not agree with DataCount section', - p.stderr) |