summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Memory64Lowering.cpp34
-rw-r--r--test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.txt3
-rw-r--r--test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.wast2
3 files changed, 36 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;
+ }
+ }
}
}
};
diff --git a/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.txt b/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.txt
index 535778232..243102f85 100644
--- a/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.txt
+++ b/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.txt
@@ -1,7 +1,10 @@
(module
(type $none_=>_none (func))
+ (import "env" "__memory_base" (global $__memory_base i64))
+ (import "env" "__memory_base32" (global $__memory_base32 i32))
(memory $0 1 1)
(data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00")
+ (data (global.get $__memory_base32) "foo")
(func $func_1
(local $0 i64)
(drop
diff --git a/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.wast b/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.wast
index c59da359d..7cb89599f 100644
--- a/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.wast
+++ b/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.wast
@@ -1,6 +1,8 @@
(module
+ (import "env" "__memory_base" (global $__memory_base i64))
(memory $0 i64 1 1)
(data (i64.const 0) "\00\00\00\00\00\00\00\00\00\00")
+ (data (global.get $__memory_base) "foo")
(func $func_1
(local i64)
(drop (i32.load (i64.const 4)))