Skip to content

Commit 849ea21

Browse files
authored
Handle sbrk import by emscripten+upstream in SafeHeap (#2332)
To allow #2331 to roll, I forgot that upstream and fastcomp handle sbrk differently. This fixes that, and handles the upstream case where we import sbrk itself from JS. We can simplify this after emscripten-core/emscripten#9397 lands, however, it may also be nice to keep the backwards compatibility for running on existing wasm files in the wild.
1 parent 77fa398 commit 849ea21

1 file changed

Lines changed: 20 additions & 10 deletions

File tree

src/passes/SafeHeap.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@
3232

3333
namespace wasm {
3434

35-
const Name DYNAMICTOP_PTR_IMPORT("DYNAMICTOP_PTR");
36-
const Name GET_SBRK_PTR_IMPORT("emscripten_get_sbrk_ptr");
37-
const Name SEGFAULT_IMPORT("segfault");
38-
const Name ALIGNFAULT_IMPORT("alignfault");
35+
static const Name DYNAMICTOP_PTR_IMPORT("DYNAMICTOP_PTR");
36+
static const Name GET_SBRK_PTR_IMPORT("emscripten_get_sbrk_ptr");
37+
static const Name SBRK("sbrk");
38+
static const Name SEGFAULT_IMPORT("segfault");
39+
static const Name ALIGNFAULT_IMPORT("alignfault");
3940

4041
static Name getLoadName(Load* curr) {
4142
std::string ret = "SAFE_HEAP_LOAD_";
@@ -112,7 +113,7 @@ struct SafeHeap : public Pass {
112113
addGlobals(module, module->features);
113114
}
114115

115-
Name dynamicTopPtr, getSbrkPtr, segfault, alignfault;
116+
Name dynamicTopPtr, getSbrkPtr, sbrk, segfault, alignfault;
116117

117118
void addImports(Module* module) {
118119
ImportInfo info(*module);
@@ -124,6 +125,8 @@ struct SafeHeap : public Pass {
124125
} else if (auto* existing =
125126
info.getImportedFunction(ENV, GET_SBRK_PTR_IMPORT)) {
126127
getSbrkPtr = existing->name;
128+
} else if (auto* existing = info.getImportedFunction(ENV, SBRK)) {
129+
sbrk = existing->name;
127130
} else {
128131
auto* import = new Function;
129132
import->name = getSbrkPtr = GET_SBRK_PTR_IMPORT;
@@ -324,11 +327,18 @@ struct SafeHeap : public Pass {
324327
makeBoundsCheck(Type type, Builder& builder, Index local, Index bytes) {
325328
auto upperOp = options.lowMemoryUnused ? LtUInt32 : EqInt32;
326329
auto upperBound = options.lowMemoryUnused ? PassOptions::LowMemoryBound : 0;
327-
Expression* sbrkPtr;
328-
if (dynamicTopPtr.is()) {
329-
sbrkPtr = builder.makeGlobalGet(dynamicTopPtr, i32);
330+
Expression* brkLocation;
331+
if (sbrk.is()) {
332+
brkLocation =
333+
builder.makeCall(sbrk, {builder.makeConst(Literal(int32_t(0)))}, i32);
330334
} else {
331-
sbrkPtr = builder.makeCall(getSbrkPtr, {}, i32);
335+
Expression* sbrkPtr;
336+
if (dynamicTopPtr.is()) {
337+
sbrkPtr = builder.makeGlobalGet(dynamicTopPtr, i32);
338+
} else {
339+
sbrkPtr = builder.makeCall(getSbrkPtr, {}, i32);
340+
}
341+
brkLocation = builder.makeLoad(4, false, 0, 4, sbrkPtr, i32);
332342
}
333343
return builder.makeIf(
334344
builder.makeBinary(
@@ -341,7 +351,7 @@ struct SafeHeap : public Pass {
341351
builder.makeBinary(AddInt32,
342352
builder.makeLocalGet(local, i32),
343353
builder.makeConst(Literal(int32_t(bytes)))),
344-
builder.makeLoad(4, false, 0, 4, sbrkPtr, i32))),
354+
brkLocation)),
345355
builder.makeCall(segfault, {}, none));
346356
}
347357
};

0 commit comments

Comments
 (0)