diff options
author | Thomas Lively <tlively@google.com> | 2023-03-10 15:30:37 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-10 21:30:37 +0000 |
commit | a389185799e39368856bc8b6a3f10eb713fc0643 (patch) | |
tree | 1ad07beddf2a9ad79c2c4e967cf7eeee58b43f77 /src/passes/MultiMemoryLowering.cpp | |
parent | 271312d06760eb3b1d8de1206cc6d00e2cf30d42 (diff) | |
download | binaryen-a389185799e39368856bc8b6a3f10eb713fc0643.tar.gz binaryen-a389185799e39368856bc8b6a3f10eb713fc0643.tar.bz2 binaryen-a389185799e39368856bc8b6a3f10eb713fc0643.zip |
Make constant expression validation stricter (#5557)
Previously we treated global.get as a constant expression and only
additionally verified that the target globals were immutable in some cases. But
global.get of a mutable global is never a constant expression, and further,
only imported globals are available in constant expressions unless GC is
enabled.
Fix constant expression validation to only allow global.get of immutable,
imported globals, and fix all the invalid tests.
Diffstat (limited to 'src/passes/MultiMemoryLowering.cpp')
-rw-r--r-- | src/passes/MultiMemoryLowering.cpp | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/src/passes/MultiMemoryLowering.cpp b/src/passes/MultiMemoryLowering.cpp index 5414f2f99..08e1622d5 100644 --- a/src/passes/MultiMemoryLowering.cpp +++ b/src/passes/MultiMemoryLowering.cpp @@ -413,6 +413,14 @@ struct MultiMemoryLowering : public Pass { return offsetGlobalNames[idx - 1]; } + size_t getInitialOffset(Index idx) { + if (idx == 0) { + return 0; + } + auto* g = wasm->getGlobal(getOffsetGlobal(idx)); + return g->init->cast<Const>()->value.getUnsigned(); + } + // Whether the idx represents the last memory. Since there is no offset global // for the first memory, the last memory is represented by the size of // offsetGlobalNames @@ -509,17 +517,11 @@ struct MultiMemoryLowering : public Pass { ModuleUtils::iterActiveDataSegments(*wasm, [&](DataSegment* dataSegment) { auto idx = memoryIdxMap.at(dataSegment->memory); dataSegment->memory = combinedMemory; - // No need to update the offset of data segments for the first memory - if (idx != 0) { - assert(dataSegment->offset->is<Const>() && - "TODO: handle non-const segment offsets"); - assert(wasm->features.hasExtendedConst()); - auto offsetGlobalName = getOffsetGlobal(idx); - dataSegment->offset = builder.makeBinary( - Abstract::getBinary(pointerType, Abstract::Add), - builder.makeGlobalGet(offsetGlobalName, pointerType), - dataSegment->offset); - } + auto* offset = dataSegment->offset->dynCast<Const>(); + assert(offset && "TODO: handle non-const segment offsets"); + size_t originalOffset = offset->value.getUnsigned(); + auto memOffset = getInitialOffset(idx); + offset->value = Literal(int32_t(originalOffset + memOffset)); }); } |