summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2019-09-05 20:19:04 -0700
committerGitHub <noreply@github.com>2019-09-05 20:19:04 -0700
commit7b4f97823cf46532ac65b980a957f67a681e3002 (patch)
tree5a175105d2bef64200e6edfc337a0d0e024e4c95 /src
parenta0c77bf09dc561f9857bd44167fb04d571e3036a (diff)
downloadbinaryen-7b4f97823cf46532ac65b980a957f67a681e3002.tar.gz
binaryen-7b4f97823cf46532ac65b980a957f67a681e3002.tar.bz2
binaryen-7b4f97823cf46532ac65b980a957f67a681e3002.zip
SafeHeap: Prepare for emscripten_get_sbrk_ptr (#2331)
Currently emscripten links the wasm, then links the JS, then computes the final static allocations and in particular the location of the sbrk ptr (i.e. the location in memory of the brk location). Emscripten then imports that into the asm.js or wasm as env.DYNAMICTOP_PTR. However, this didn't work in the wasm backend where we didn't have support for importing globals from JS, so we implement sbrk in JS. I am proposing that we change this model to allow us to write sbrk in C and compile it to wasm. To do so, that C code can import an extern C function, emscripten_get_sbrk_ptr(), which basically just returns that location. The PostEmscripten pass can even apply that value at compile time, so we avoid the function call, and end up in the optimal place, see #2325 and emscripten PRs will be opened once other stuff lands. However, the SafeHeap pass must be updated to handle this, or our CI will break in the middle. This PR fixes that, basically making it check if env.DYNAMICTOP_PTR exists, or if not then looking for env.emscripten_get_sbrk_ptr, so that it can handle both.
Diffstat (limited to 'src')
-rw-r--r--src/passes/SafeHeap.cpp30
1 files changed, 22 insertions, 8 deletions
diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp
index afcfcdb5a..6957478cf 100644
--- a/src/passes/SafeHeap.cpp
+++ b/src/passes/SafeHeap.cpp
@@ -33,6 +33,7 @@
namespace wasm {
const Name DYNAMICTOP_PTR_IMPORT("DYNAMICTOP_PTR");
+const Name GET_SBRK_PTR_IMPORT("emscripten_get_sbrk_ptr");
const Name SEGFAULT_IMPORT("segfault");
const Name ALIGNFAULT_IMPORT("alignfault");
@@ -111,19 +112,27 @@ struct SafeHeap : public Pass {
addGlobals(module, module->features);
}
- Name dynamicTopPtr, segfault, alignfault;
+ Name dynamicTopPtr, getSbrkPtr, segfault, alignfault;
void addImports(Module* module) {
ImportInfo info(*module);
+ // Older emscripten imports env.DYNAMICTOP_PTR.
+ // Newer emscripten imports emscripten_get_sbrk_ptr(), which is later
+ // optimized to have the number in the binary.
if (auto* existing = info.getImportedGlobal(ENV, DYNAMICTOP_PTR_IMPORT)) {
dynamicTopPtr = existing->name;
+ } else if (auto* existing =
+ info.getImportedFunction(ENV, GET_SBRK_PTR_IMPORT)) {
+ getSbrkPtr = existing->name;
} else {
- auto* import = new Global;
- import->name = dynamicTopPtr = DYNAMICTOP_PTR_IMPORT;
+ auto* import = new Function;
+ import->name = getSbrkPtr = GET_SBRK_PTR_IMPORT;
import->module = ENV;
- import->base = DYNAMICTOP_PTR_IMPORT;
- import->type = i32;
- module->addGlobal(import);
+ import->base = GET_SBRK_PTR_IMPORT;
+ auto* functionType = ensureFunctionType("i", module);
+ import->type = functionType->name;
+ FunctionTypeUtils::fillFunction(import, functionType);
+ module->addFunction(import);
}
if (auto* existing = info.getImportedFunction(ENV, SEGFAULT_IMPORT)) {
segfault = existing->name;
@@ -315,6 +324,12 @@ struct SafeHeap : public Pass {
makeBoundsCheck(Type type, Builder& builder, Index local, Index bytes) {
auto upperOp = options.lowMemoryUnused ? LtUInt32 : EqInt32;
auto upperBound = options.lowMemoryUnused ? PassOptions::LowMemoryBound : 0;
+ Expression* sbrkPtr;
+ if (dynamicTopPtr.is()) {
+ sbrkPtr = builder.makeGlobalGet(dynamicTopPtr, i32);
+ } else {
+ sbrkPtr = builder.makeCall(getSbrkPtr, {}, i32);
+ }
return builder.makeIf(
builder.makeBinary(
OrInt32,
@@ -326,8 +341,7 @@ struct SafeHeap : public Pass {
builder.makeBinary(AddInt32,
builder.makeLocalGet(local, i32),
builder.makeConst(Literal(int32_t(bytes)))),
- builder.makeLoad(
- 4, false, 0, 4, builder.makeGlobalGet(dynamicTopPtr, i32), i32))),
+ builder.makeLoad(4, false, 0, 4, sbrkPtr, i32))),
builder.makeCall(segfault, {}, none));
}
};