diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-binary.h | 10 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 24 |
2 files changed, 33 insertions, 1 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 50b78fbae..1f6222cba 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -322,7 +322,8 @@ enum Section { Start = 8, Element = 9, Code = 10, - Data = 11 + Data = 11, + DataCount = 12, }; enum SegmentFlag { @@ -891,6 +892,7 @@ public: void writeFunctions(); void writeGlobals(); void writeExports(); + void writeDataCount(); void writeDataSegments(); std::unordered_map<Name, Index> mappedFunctions; // name of the Function => index. first imports, then internals @@ -1083,8 +1085,14 @@ public: std::map<Index, Name> mappedGlobals; // index of the Global => name. first imported globals, then internal globals Name getGlobalName(Index index); + void validateBinary(); // validations that cannot be performed on the Module void processFunctions(); + + size_t dataCount = 0; + bool hasDataCount = false; + void readDataSegments(); + void readDataCount(); std::map<Index, std::vector<Index>> functionTable; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index b351a46e5..f3642203d 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -58,6 +58,7 @@ void WasmBinaryWriter::write() { writeExports(); writeStart(); writeTableElements(); + writeDataCount(); writeFunctions(); writeDataSegments(); if (debugInfo) writeNames(); @@ -312,6 +313,15 @@ void WasmBinaryWriter::writeExports() { finishSection(start); } +void WasmBinaryWriter::writeDataCount() { + if (!wasm->features.hasBulkMemory() || !wasm->memory.segments.size()) { + return; + } + auto start = startSection(BinaryConsts::Section::DataCount); + o << U32LEB(wasm->memory.segments.size()); + finishSection(start); +} + void WasmBinaryWriter::writeDataSegments() { if (wasm->memory.segments.size() == 0) return; if (wasm->memory.segments.size() > WebLimitations::MaxDataSegments) { @@ -657,6 +667,7 @@ void WasmBinaryBuilder::read() { break; } case BinaryConsts::Section::Data: readDataSegments(); break; + case BinaryConsts::Section::DataCount: readDataCount(); break; case BinaryConsts::Section::Table: readFunctionTableDeclaration(); break; default: { readUserSection(payloadLen); @@ -673,6 +684,7 @@ void WasmBinaryBuilder::read() { } } + validateBinary(); processFunctions(); } @@ -1457,6 +1469,12 @@ Name WasmBinaryBuilder::getGlobalName(Index index) { return mappedGlobals[index]; } +void WasmBinaryBuilder::validateBinary() { + if (hasDataCount && wasm.memory.segments.size() != dataCount) { + throwError("Number of segments does not agree with DataCount section"); + } +} + void WasmBinaryBuilder::processFunctions() { for (auto* func : functions) { wasm.addFunction(func); @@ -1504,6 +1522,12 @@ void WasmBinaryBuilder::processFunctions() { wasm.updateMaps(); } +void WasmBinaryBuilder::readDataCount() { + if (debug) std::cerr << "== readDataCount" << std::endl; + hasDataCount = true; + dataCount = getU32LEB(); +} + void WasmBinaryBuilder::readDataSegments() { if (debug) std::cerr << "== readDataSegments" << std::endl; auto num = getU32LEB(); |