summaryrefslogtreecommitdiff
path: root/src/passes
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes')
-rw-r--r--src/passes/AlignmentLowering.cpp52
-rw-r--r--src/passes/AvoidReinterprets.cpp9
-rw-r--r--src/passes/InstrumentMemory.cpp17
-rw-r--r--src/passes/MemoryPacking.cpp22
-rw-r--r--src/passes/OptimizeInstructions.cpp18
-rw-r--r--src/passes/Print.cpp5
-rw-r--r--src/passes/SafeHeap.cpp102
-rw-r--r--src/passes/StackIR.cpp2
8 files changed, 129 insertions, 98 deletions
diff --git a/src/passes/AlignmentLowering.cpp b/src/passes/AlignmentLowering.cpp
index b12e49c4f..8cab58072 100644
--- a/src/passes/AlignmentLowering.cpp
+++ b/src/passes/AlignmentLowering.cpp
@@ -34,9 +34,10 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
if (curr->align == 0 || curr->align == curr->bytes) {
return curr;
}
+ auto indexType = getModule()->memory.indexType;
Builder builder(*getModule());
assert(curr->type == Type::i32);
- auto temp = builder.addVar(getFunction(), Type::i32);
+ auto temp = builder.addVar(getFunction(), indexType);
Expression* ret;
if (curr->bytes == 2) {
ret = builder.makeBinary(
@@ -45,7 +46,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
false,
curr->offset,
1,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32),
builder.makeBinary(
ShlInt32,
@@ -53,7 +54,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
false,
curr->offset + 1,
1,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32),
builder.makeConst(int32_t(8))));
if (curr->signed_) {
@@ -69,7 +70,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
false,
curr->offset,
1,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32),
builder.makeBinary(
ShlInt32,
@@ -77,7 +78,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
false,
curr->offset + 1,
1,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32),
builder.makeConst(int32_t(8)))),
builder.makeBinary(
@@ -88,7 +89,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
false,
curr->offset + 2,
1,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32),
builder.makeConst(int32_t(16))),
builder.makeBinary(
@@ -97,7 +98,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
false,
curr->offset + 3,
1,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32),
builder.makeConst(int32_t(24)))));
} else if (curr->align == 2) {
@@ -107,7 +108,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
false,
curr->offset,
2,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32),
builder.makeBinary(
ShlInt32,
@@ -115,7 +116,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
false,
curr->offset + 2,
2,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32),
builder.makeConst(int32_t(16))));
} else {
@@ -134,7 +135,8 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
}
Builder builder(*getModule());
assert(curr->value->type == Type::i32);
- auto tempPtr = builder.addVar(getFunction(), Type::i32);
+ auto indexType = getModule()->memory.indexType;
+ auto tempPtr = builder.addVar(getFunction(), indexType);
auto tempValue = builder.addVar(getFunction(), Type::i32);
auto* block =
builder.makeBlock({builder.makeLocalSet(tempPtr, curr->ptr),
@@ -144,14 +146,14 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
builder.makeStore(1,
curr->offset,
1,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
builder.makeLocalGet(tempValue, Type::i32),
Type::i32));
block->list.push_back(builder.makeStore(
1,
curr->offset + 1,
1,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
builder.makeBinary(ShrUInt32,
builder.makeLocalGet(tempValue, Type::i32),
builder.makeConst(int32_t(8))),
@@ -162,14 +164,14 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
builder.makeStore(1,
curr->offset,
1,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
builder.makeLocalGet(tempValue, Type::i32),
Type::i32));
block->list.push_back(builder.makeStore(
1,
curr->offset + 1,
1,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
builder.makeBinary(ShrUInt32,
builder.makeLocalGet(tempValue, Type::i32),
builder.makeConst(int32_t(8))),
@@ -178,7 +180,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
1,
curr->offset + 2,
1,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
builder.makeBinary(ShrUInt32,
builder.makeLocalGet(tempValue, Type::i32),
builder.makeConst(int32_t(16))),
@@ -187,7 +189,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
1,
curr->offset + 3,
1,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
builder.makeBinary(ShrUInt32,
builder.makeLocalGet(tempValue, Type::i32),
builder.makeConst(int32_t(24))),
@@ -197,14 +199,14 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
builder.makeStore(2,
curr->offset,
2,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
builder.makeLocalGet(tempValue, Type::i32),
Type::i32));
block->list.push_back(builder.makeStore(
2,
curr->offset + 2,
2,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
builder.makeBinary(ShrUInt32,
builder.makeLocalGet(tempValue, Type::i32),
builder.makeConst(int32_t(16))),
@@ -254,14 +256,15 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
break;
}
// Load two 32-bit pieces, and combine them.
- auto temp = builder.addVar(getFunction(), Type::i32);
+ auto indexType = getModule()->memory.indexType;
+ auto temp = builder.addVar(getFunction(), indexType);
auto* set = builder.makeLocalSet(temp, curr->ptr);
Expression* low =
lowerLoadI32(builder.makeLoad(4,
false,
curr->offset,
curr->align,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32));
low = builder.makeUnary(ExtendUInt32, low);
// Note that the alignment is assumed to be the same here, even though
@@ -273,7 +276,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
false,
curr->offset + 4,
curr->align,
- builder.makeLocalGet(temp, Type::i32),
+ builder.makeLocalGet(temp, indexType),
Type::i32));
high = builder.makeUnary(ExtendUInt32, high);
high =
@@ -332,7 +335,8 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
value = builder.makeUnary(ReinterpretFloat64, value);
}
// Store as two 32-bit pieces.
- auto tempPtr = builder.addVar(getFunction(), Type::i32);
+ auto indexType = getModule()->memory.indexType;
+ auto tempPtr = builder.addVar(getFunction(), indexType);
auto* setPtr = builder.makeLocalSet(tempPtr, curr->ptr);
auto tempValue = builder.addVar(getFunction(), Type::i64);
auto* setValue = builder.makeLocalSet(tempValue, value);
@@ -342,7 +346,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
builder.makeStore(4,
curr->offset,
curr->align,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
low,
Type::i32));
Expression* high =
@@ -358,7 +362,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> {
builder.makeStore(4,
curr->offset + 4,
curr->align,
- builder.makeLocalGet(tempPtr, Type::i32),
+ builder.makeLocalGet(tempPtr, indexType),
high,
Type::i32));
replacement = builder.makeBlock({setPtr, setValue, low, high});
diff --git a/src/passes/AvoidReinterprets.cpp b/src/passes/AvoidReinterprets.cpp
index 8668b9703..cc5871a2a 100644
--- a/src/passes/AvoidReinterprets.cpp
+++ b/src/passes/AvoidReinterprets.cpp
@@ -117,12 +117,13 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> {
void optimize(Function* func) {
std::set<Load*> unoptimizables;
+ auto indexType = getModule()->memory.indexType;
for (auto& pair : infos) {
auto* load = pair.first;
auto& info = pair.second;
if (info.reinterpreted && canReplaceWithReinterpret(load)) {
// We should use another load here, to avoid reinterprets.
- info.ptrLocal = Builder::addVar(func, Type::i32);
+ info.ptrLocal = Builder::addVar(func, indexType);
info.reinterpretedLocal =
Builder::addVar(func, load->type.reinterpret());
} else {
@@ -176,7 +177,8 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> {
auto& info = iter->second;
Builder builder(*module);
auto* ptr = curr->ptr;
- curr->ptr = builder.makeLocalGet(info.ptrLocal, Type::i32);
+ auto indexType = getModule()->memory.indexType;
+ curr->ptr = builder.makeLocalGet(info.ptrLocal, indexType);
// Note that the other load can have its sign set to false - if the
// original were an integer, the other is a float anyhow; and if
// original were a float, we don't know what sign to use.
@@ -185,7 +187,7 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> {
builder.makeLocalSet(
info.reinterpretedLocal,
makeReinterpretedLoad(
- curr, builder.makeLocalGet(info.ptrLocal, Type::i32))),
+ curr, builder.makeLocalGet(info.ptrLocal, indexType))),
curr}));
}
}
@@ -201,6 +203,7 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> {
}
} finalOptimizer(infos, localGraph, getModule(), getPassOptions());
+ finalOptimizer.setModule(getModule());
finalOptimizer.walk(func->body);
}
};
diff --git a/src/passes/InstrumentMemory.cpp b/src/passes/InstrumentMemory.cpp
index fca3ff510..9e4788456 100644
--- a/src/passes/InstrumentMemory.cpp
+++ b/src/passes/InstrumentMemory.cpp
@@ -78,12 +78,14 @@ struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> {
void visitLoad(Load* curr) {
id++;
Builder builder(*getModule());
+ auto indexType = getModule()->memory.indexType;
+ auto offset = builder.makeConstPtr(curr->offset.addr);
curr->ptr = builder.makeCall(load_ptr,
{builder.makeConst(int32_t(id)),
builder.makeConst(int32_t(curr->bytes)),
- builder.makeConst(int32_t(curr->offset.addr)),
+ offset,
curr->ptr},
- Type::i32);
+ indexType);
Name target;
switch (curr->type.getBasic()) {
case Type::i32:
@@ -108,12 +110,14 @@ struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> {
void visitStore(Store* curr) {
id++;
Builder builder(*getModule());
+ auto indexType = getModule()->memory.indexType;
+ auto offset = builder.makeConstPtr(curr->offset.addr);
curr->ptr = builder.makeCall(store_ptr,
{builder.makeConst(int32_t(id)),
builder.makeConst(int32_t(curr->bytes)),
- builder.makeConst(int32_t(curr->offset.addr)),
+ offset,
curr->ptr},
- Type::i32);
+ indexType);
Name target;
switch (curr->value->type.getBasic()) {
case Type::i32:
@@ -136,14 +140,15 @@ struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> {
}
void visitModule(Module* curr) {
+ auto indexType = curr->memory.indexType;
addImport(
- curr, load_ptr, {Type::i32, Type::i32, Type::i32, Type::i32}, Type::i32);
+ curr, load_ptr, {Type::i32, Type::i32, indexType, indexType}, indexType);
addImport(curr, load_val_i32, {Type::i32, Type::i32}, Type::i32);
addImport(curr, load_val_i64, {Type::i32, Type::i64}, Type::i64);
addImport(curr, load_val_f32, {Type::i32, Type::f32}, Type::f32);
addImport(curr, load_val_f64, {Type::i32, Type::f64}, Type::f64);
addImport(
- curr, store_ptr, {Type::i32, Type::i32, Type::i32, Type::i32}, Type::i32);
+ curr, store_ptr, {Type::i32, Type::i32, indexType, indexType}, indexType);
addImport(curr, store_val_i32, {Type::i32, Type::i32}, Type::i32);
addImport(curr, store_val_i64, {Type::i32, Type::i64}, Type::i64);
addImport(curr, store_val_f32, {Type::i32, Type::f32}, Type::f32);
diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp
index eac7fb7f0..1018ce1c7 100644
--- a/src/passes/MemoryPacking.cpp
+++ b/src/passes/MemoryPacking.cpp
@@ -76,9 +76,14 @@ const size_t DATA_DROP_SIZE = 3;
namespace {
-Expression* makeShiftedMemorySize(Builder& builder) {
+Expression*
+makeGtShiftedMemorySize(Builder& builder, Module& module, MemoryInit* curr) {
return builder.makeBinary(
- ShlInt32, builder.makeMemorySize(), builder.makeConst(int32_t(16)));
+ module.memory.is64() ? GtUInt64 : GtUInt32,
+ curr->dest,
+ builder.makeBinary(module.memory.is64() ? ShlInt64 : ShlInt32,
+ builder.makeMemorySize(),
+ builder.makeConstPtr(16)));
}
} // anonymous namespace
@@ -317,10 +322,9 @@ void MemoryPacking::optimizeBulkMemoryOps(PassRunner* runner, Module* module) {
assert(!mustNop || !mustTrap);
if (mustNop) {
// Offset and size are 0, so just trap if dest > memory.size
- replaceCurrent(builder.makeIf(
- builder.makeBinary(
- GtUInt32, curr->dest, makeShiftedMemorySize(builder)),
- builder.makeUnreachable()));
+ replaceCurrent(
+ builder.makeIf(makeGtShiftedMemorySize(builder, *getModule(), curr),
+ builder.makeUnreachable()));
} else if (mustTrap) {
// Drop dest, offset, and size then trap
replaceCurrent(builder.blockify(builder.makeDrop(curr->dest),
@@ -333,8 +337,7 @@ void MemoryPacking::optimizeBulkMemoryOps(PassRunner* runner, Module* module) {
replaceCurrent(builder.makeIf(
builder.makeBinary(
OrInt32,
- builder.makeBinary(
- GtUInt32, curr->dest, makeShiftedMemorySize(builder)),
+ makeGtShiftedMemorySize(builder, *getModule(), curr),
builder.makeBinary(OrInt32, curr->offset, curr->size)),
builder.makeUnreachable()));
}
@@ -527,8 +530,7 @@ void MemoryPacking::createReplacements(Module* module,
Expression* result = builder.makeIf(
builder.makeBinary(
OrInt32,
- builder.makeBinary(
- GtUInt32, init->dest, makeShiftedMemorySize(builder)),
+ makeGtShiftedMemorySize(builder, *module, init),
builder.makeGlobalGet(getDropStateGlobal(), Type::i32)),
builder.makeUnreachable());
replacements[init] = [result](Function*) { return result; };
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index e3d2b3a57..9cc16004d 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1107,14 +1107,20 @@ private:
// as for readability.
auto* last = ptr->dynCast<Const>();
if (last) {
- // don't do this if it would wrap the pointer
- uint64_t value64 = last->value.geti32();
+ uint64_t value64 = last->value.getInteger();
uint64_t offset64 = offset;
- if (value64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&
- offset64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&
- value64 + offset64 <= uint64_t(std::numeric_limits<int32_t>::max())) {
- last->value = Literal(int32_t(value64 + offset64));
+ if (getModule()->memory.is64()) {
+ last->value = Literal(int64_t(value64 + offset64));
offset = 0;
+ } else {
+ // don't do this if it would wrap the pointer
+ if (value64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&
+ offset64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&
+ value64 + offset64 <=
+ uint64_t(std::numeric_limits<int32_t>::max())) {
+ last->value = Literal(int32_t(value64 + offset64));
+ offset = 0;
+ }
}
}
}
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 916615e07..6955a7a5e 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -2298,6 +2298,9 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
o << '(';
printMedium(o, "shared ");
}
+ if (curr->is64()) {
+ o << "i64 ";
+ }
o << curr->initial;
if (curr->hasMax()) {
o << ' ' << curr->max;
@@ -2446,7 +2449,7 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
<< section.data.size();
bool isPrintable = true;
for (auto c : section.data) {
- if (!isprint(c)) {
+ if (!isprint(static_cast<unsigned char>(c))) {
isPrintable = false;
break;
}
diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp
index 108739d66..0335c174e 100644
--- a/src/passes/SafeHeap.cpp
+++ b/src/passes/SafeHeap.cpp
@@ -85,10 +85,7 @@ struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> {
Builder builder(*getModule());
replaceCurrent(
builder.makeCall(getLoadName(curr),
- {
- curr->ptr,
- builder.makeConst(Literal(int32_t(curr->offset))),
- },
+ {curr->ptr, builder.makeConstPtr(curr->offset.addr)},
curr->type));
}
@@ -97,14 +94,10 @@ struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> {
return;
}
Builder builder(*getModule());
- replaceCurrent(
- builder.makeCall(getStoreName(curr),
- {
- curr->ptr,
- builder.makeConst(Literal(int32_t(curr->offset))),
- curr->value,
- },
- Type::none));
+ replaceCurrent(builder.makeCall(
+ getStoreName(curr),
+ {curr->ptr, builder.makeConstPtr(curr->offset.addr), curr->value},
+ Type::none));
}
};
@@ -125,6 +118,7 @@ struct SafeHeap : public Pass {
void addImports(Module* module) {
ImportInfo info(*module);
+ auto indexType = module->memory.indexType;
// Older emscripten imports env.DYNAMICTOP_PTR.
// Newer emscripten imports or exports emscripten_get_sbrk_ptr().
if (auto* existing = info.getImportedGlobal(ENV, DYNAMICTOP_PTR_IMPORT)) {
@@ -140,7 +134,7 @@ struct SafeHeap : public Pass {
import->name = getSbrkPtr = GET_SBRK_PTR;
import->module = ENV;
import->base = GET_SBRK_PTR;
- import->sig = Signature(Type::none, Type::i32);
+ import->sig = Signature(Type::none, indexType);
module->addFunction(import);
}
if (auto* existing = info.getImportedFunction(ENV, SEGFAULT_IMPORT)) {
@@ -251,25 +245,27 @@ struct SafeHeap : public Pass {
auto* func = new Function;
func->name = name;
// pointer, offset
- func->sig = Signature({Type::i32, Type::i32}, style.type);
- func->vars.push_back(Type::i32); // pointer + offset
+ auto indexType = module->memory.indexType;
+ func->sig = Signature({indexType, indexType}, style.type);
+ func->vars.push_back(indexType); // pointer + offset
Builder builder(*module);
auto* block = builder.makeBlock();
block->list.push_back(builder.makeLocalSet(
2,
- builder.makeBinary(AddInt32,
- builder.makeLocalGet(0, Type::i32),
- builder.makeLocalGet(1, Type::i32))));
+ builder.makeBinary(module->memory.is64() ? AddInt64 : AddInt32,
+ builder.makeLocalGet(0, indexType),
+ builder.makeLocalGet(1, indexType))));
// check for reading past valid memory: if pointer + offset + bytes
- block->list.push_back(makeBoundsCheck(style.type, builder, 2, style.bytes));
+ block->list.push_back(
+ makeBoundsCheck(style.type, builder, 2, style.bytes, module));
// check proper alignment
if (style.align > 1) {
- block->list.push_back(makeAlignCheck(style.align, builder, 2));
+ block->list.push_back(makeAlignCheck(style.align, builder, 2, module));
}
// do the load
auto* load = module->allocator.alloc<Load>();
*load = style; // basically the same as the template we are given!
- load->ptr = builder.makeLocalGet(2, Type::i32);
+ load->ptr = builder.makeLocalGet(2, indexType);
Expression* last = load;
if (load->isAtomic && load->signed_) {
// atomic loads cannot be signed, manually sign it
@@ -291,26 +287,27 @@ struct SafeHeap : public Pass {
auto* func = new Function;
func->name = name;
// pointer, offset, value
- func->sig = Signature({Type::i32, Type::i32, style.valueType}, Type::none);
- func->vars.push_back(Type::i32); // pointer + offset
+ auto indexType = module->memory.indexType;
+ func->sig = Signature({indexType, indexType, style.valueType}, Type::none);
+ func->vars.push_back(indexType); // pointer + offset
Builder builder(*module);
auto* block = builder.makeBlock();
block->list.push_back(builder.makeLocalSet(
3,
- builder.makeBinary(AddInt32,
- builder.makeLocalGet(0, Type::i32),
- builder.makeLocalGet(1, Type::i32))));
+ builder.makeBinary(module->memory.is64() ? AddInt64 : AddInt32,
+ builder.makeLocalGet(0, indexType),
+ builder.makeLocalGet(1, indexType))));
// check for reading past valid memory: if pointer + offset + bytes
block->list.push_back(
- makeBoundsCheck(style.valueType, builder, 3, style.bytes));
+ makeBoundsCheck(style.valueType, builder, 3, style.bytes, module));
// check proper alignment
if (style.align > 1) {
- block->list.push_back(makeAlignCheck(style.align, builder, 3));
+ block->list.push_back(makeAlignCheck(style.align, builder, 3, module));
}
// do the store
auto* store = module->allocator.alloc<Store>();
*store = style; // basically the same as the template we are given!
- store->ptr = builder.makeLocalGet(3, Type::i32);
+ store->ptr = builder.makeLocalGet(3, indexType);
store->value = builder.makeLocalGet(2, style.valueType);
block->list.push_back(store);
block->finalize(Type::none);
@@ -318,42 +315,53 @@ struct SafeHeap : public Pass {
module->addFunction(func);
}
- Expression* makeAlignCheck(Address align, Builder& builder, Index local) {
+ Expression*
+ makeAlignCheck(Address align, Builder& builder, Index local, Module* module) {
+ auto indexType = module->memory.indexType;
+ Expression* ptrBits = builder.makeLocalGet(local, indexType);
+ if (module->memory.is64()) {
+ ptrBits = builder.makeUnary(WrapInt64, ptrBits);
+ }
return builder.makeIf(
- builder.makeBinary(AndInt32,
- builder.makeLocalGet(local, Type::i32),
- builder.makeConst(Literal(int32_t(align - 1)))),
+ builder.makeBinary(
+ AndInt32, ptrBits, builder.makeConst(int32_t(align - 1))),
builder.makeCall(alignfault, {}, Type::none));
}
- Expression*
- makeBoundsCheck(Type type, Builder& builder, Index local, Index bytes) {
- auto upperOp = options.lowMemoryUnused ? LtUInt32 : EqInt32;
+ Expression* makeBoundsCheck(
+ Type type, Builder& builder, Index local, Index bytes, Module* module) {
+ auto indexType = module->memory.indexType;
+ auto upperOp = module->memory.is64()
+ ? options.lowMemoryUnused ? LtUInt64 : EqInt64
+ : options.lowMemoryUnused ? LtUInt32 : EqInt32;
auto upperBound = options.lowMemoryUnused ? PassOptions::LowMemoryBound : 0;
Expression* brkLocation;
if (sbrk.is()) {
- brkLocation = builder.makeCall(
- sbrk, {builder.makeConst(Literal(int32_t(0)))}, Type::i32);
+ brkLocation =
+ builder.makeCall(sbrk, {builder.makeConstPtr(0)}, indexType);
} else {
Expression* sbrkPtr;
if (dynamicTopPtr.is()) {
- sbrkPtr = builder.makeGlobalGet(dynamicTopPtr, Type::i32);
+ sbrkPtr = builder.makeGlobalGet(dynamicTopPtr, indexType);
} else {
- sbrkPtr = builder.makeCall(getSbrkPtr, {}, Type::i32);
+ sbrkPtr = builder.makeCall(getSbrkPtr, {}, indexType);
}
- brkLocation = builder.makeLoad(4, false, 0, 4, sbrkPtr, Type::i32);
+ auto size = module->memory.is64() ? 8 : 4;
+ brkLocation = builder.makeLoad(size, false, 0, size, sbrkPtr, indexType);
}
+ auto gtuOp = module->memory.is64() ? GtUInt64 : GtUInt32;
+ auto addOp = module->memory.is64() ? AddInt64 : AddInt32;
return builder.makeIf(
builder.makeBinary(
OrInt32,
builder.makeBinary(upperOp,
- builder.makeLocalGet(local, Type::i32),
- builder.makeConst(Literal(int32_t(upperBound)))),
+ builder.makeLocalGet(local, indexType),
+ builder.makeConstPtr(upperBound)),
builder.makeBinary(
- GtUInt32,
- builder.makeBinary(AddInt32,
- builder.makeLocalGet(local, Type::i32),
- builder.makeConst(Literal(int32_t(bytes)))),
+ gtuOp,
+ builder.makeBinary(addOp,
+ builder.makeLocalGet(local, indexType),
+ builder.makeConstPtr(bytes)),
brkLocation)),
builder.makeCall(segfault, {}, Type::none));
}
diff --git a/src/passes/StackIR.cpp b/src/passes/StackIR.cpp
index a628468fb..ee2062b3d 100644
--- a/src/passes/StackIR.cpp
+++ b/src/passes/StackIR.cpp
@@ -36,7 +36,7 @@ struct GenerateStackIR : public WalkerPass<PostWalker<GenerateStackIR>> {
bool modifiesBinaryenIR() override { return false; }
void doWalkFunction(Function* func) {
- StackIRGenerator stackIRGen(getModule()->allocator, func);
+ StackIRGenerator stackIRGen(*getModule(), func);
stackIRGen.write();
func->stackIR = make_unique<StackIR>();
func->stackIR->swap(stackIRGen.getStackIR());