summaryrefslogtreecommitdiff
path: root/src/passes/Memory64Lowering.cpp
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2024-05-15 12:53:31 -0700
committerGitHub <noreply@github.com>2024-05-15 12:53:31 -0700
commit2b60f8a212c0e744d0dbf3346498b08c9a27a39e (patch)
treeee80a2e5a894c2af40972c269f2bb69089e9fdc0 /src/passes/Memory64Lowering.cpp
parent2cc5e06549a4019eeed7303bfab32b95c32507bc (diff)
downloadbinaryen-2b60f8a212c0e744d0dbf3346498b08c9a27a39e.tar.gz
binaryen-2b60f8a212c0e744d0dbf3346498b08c9a27a39e.tar.bz2
binaryen-2b60f8a212c0e744d0dbf3346498b08c9a27a39e.zip
Add table64 lowering pass (#6595)
Changes to wasm-validator.cpp here are mostly for consistency between elem and data segment validation.
Diffstat (limited to 'src/passes/Memory64Lowering.cpp')
-rw-r--r--src/passes/Memory64Lowering.cpp75
1 files changed, 39 insertions, 36 deletions
diff --git a/src/passes/Memory64Lowering.cpp b/src/passes/Memory64Lowering.cpp
index e0301936a..0a58fed13 100644
--- a/src/passes/Memory64Lowering.cpp
+++ b/src/passes/Memory64Lowering.cpp
@@ -38,11 +38,10 @@ struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {
return;
}
auto& module = *getModule();
- auto memory = module.getMemory(memoryName);
+ auto* memory = module.getMemory(memoryName);
if (memory->is64()) {
assert(ptr->type == Type::i64);
- Builder builder(module);
- ptr = builder.makeUnary(UnaryOp::WrapInt64, ptr);
+ ptr = Builder(module).makeUnary(UnaryOp::WrapInt64, ptr);
}
}
@@ -51,12 +50,11 @@ struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {
return;
}
auto& module = *getModule();
- auto memory = module.getMemory(memoryName);
+ auto* memory = module.getMemory(memoryName);
if (memory->is64()) {
assert(ptr->type == Type::i64);
ptr->type = Type::i32;
- Builder builder(module);
- ptr = builder.makeUnary(UnaryOp::ExtendUInt32, ptr);
+ ptr = Builder(module).makeUnary(UnaryOp::ExtendUInt32, ptr);
}
}
@@ -66,9 +64,9 @@ struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {
void visitMemorySize(MemorySize* curr) {
auto& module = *getModule();
- auto memory = module.getMemory(curr->memory);
+ auto* memory = module.getMemory(curr->memory);
if (memory->is64()) {
- auto size = static_cast<Expression*>(curr);
+ auto* size = static_cast<Expression*>(curr);
extendAddress64(size, curr->memory);
curr->type = Type::i32;
replaceCurrent(size);
@@ -77,10 +75,10 @@ struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {
void visitMemoryGrow(MemoryGrow* curr) {
auto& module = *getModule();
- auto memory = module.getMemory(curr->memory);
+ auto* memory = module.getMemory(curr->memory);
if (memory->is64()) {
wrapAddress64(curr->delta, curr->memory);
- auto size = static_cast<Expression*>(curr);
+ auto* size = static_cast<Expression*>(curr);
extendAddress64(size, curr->memory);
curr->type = Type::i32;
replaceCurrent(size);
@@ -129,34 +127,39 @@ struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {
}
void visitDataSegment(DataSegment* segment) {
- if (!segment->isPassive) {
- 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;
+ if (segment->isPassive) {
+ // passive segments don't have any offset to adjust
+ return;
+ }
+
+ 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;
}
+ } else {
+ WASM_UNREACHABLE("unexpected elem offset");
}
}