summaryrefslogtreecommitdiff
path: root/src/passes/Memory64Lowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/Memory64Lowering.cpp')
-rw-r--r--src/passes/Memory64Lowering.cpp34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/passes/Memory64Lowering.cpp b/src/passes/Memory64Lowering.cpp
index 15f3a7719..661d6cdae 100644
--- a/src/passes/Memory64Lowering.cpp
+++ b/src/passes/Memory64Lowering.cpp
@@ -21,12 +21,16 @@
// TODO(wvo): make this run in parallel if needed.
#include "ir/bits.h"
+#include "ir/import-utils.h"
#include "pass.h"
#include "wasm-builder.h"
#include "wasm.h"
namespace wasm {
+static Name MEMORY_BASE("__memory_base");
+static Name MEMORY_BASE32("__memory_base32");
+
struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {
void wrapAddress64(Expression*& ptr, Name memoryName) {
@@ -126,9 +130,33 @@ struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {
void visitDataSegment(DataSegment* segment) {
if (!segment->isPassive) {
- auto* c = segment->offset->cast<Const>();
- c->value = Literal(static_cast<uint32_t>(c->value.geti64()));
- c->type = Type::i32;
+ if (auto* c = segment->offset->dynCast<Const>()) {
+ c->value = Literal(static_cast<uint32_t>(c->value.geti64()));
+ c->type = Type::i32;
+ } else if (auto* get = segment->offset->dynCast<GlobalGet>()) {
+ auto& module = *getModule();
+ auto* g = module.getGlobal(get->name);
+ if (g->imported() && g->base == MEMORY_BASE) {
+ ImportInfo info(module);
+ auto* memoryBase32 = info.getImportedGlobal(g->module, MEMORY_BASE32);
+ if (!memoryBase32) {
+ Builder builder(module);
+ memoryBase32 = builder
+ .makeGlobal(MEMORY_BASE32,
+ Type::i32,
+ builder.makeConst(int32_t(0)),
+ Builder::Immutable)
+ .release();
+ memoryBase32->module = g->module;
+ memoryBase32->base = MEMORY_BASE32;
+ module.addGlobal(memoryBase32);
+ }
+ // Use this alternative import when initializing the segment.
+ assert(memoryBase32);
+ get->type = Type::i32;
+ get->name = memoryBase32->name;
+ }
+ }
}
}
};