summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2018-12-11 15:29:02 -0800
committerAlon Zakai <alonzakai@gmail.com>2018-12-11 16:35:55 -0800
commit3307ca89fc270bdca7e5124dca8dcb54027918c2 (patch)
tree88c0229245880a0ab64e4f7f3f809aaec2acf2fb
parent60b57973318faca7b5f42a25323209763980283c (diff)
downloadbinaryen-3307ca89fc270bdca7e5124dca8dcb54027918c2.tar.gz
binaryen-3307ca89fc270bdca7e5124dca8dcb54027918c2.tar.bz2
binaryen-3307ca89fc270bdca7e5124dca8dcb54027918c2.zip
wasm-ctor-eval: handle the stack going either up or down
-rw-r--r--src/tools/wasm-ctor-eval.cpp25
-rw-r--r--test/ctor-eval/stack-direction.wast30
-rw-r--r--test/ctor-eval/stack-direction.wast.ctors1
-rw-r--r--test/ctor-eval/stack-direction.wast.out2
4 files changed, 48 insertions, 10 deletions
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp
index 53f33944e..b0e2e2ce7 100644
--- a/src/tools/wasm-ctor-eval.cpp
+++ b/src/tools/wasm-ctor-eval.cpp
@@ -113,12 +113,17 @@ public:
}
};
-enum {
- // put the stack in some ridiculously high location
- STACK_START = 0x40000000,
- // use a ridiculously large stack size
- STACK_SIZE = 32 * 1024 * 1024
-};
+// Use a ridiculously large stack size.
+static Index STACK_SIZE = 32 * 1024 * 1024;
+
+// Start the stack at a ridiculously large location, and do so in
+// a way that works regardless if the stack goes up or down.
+static Index STACK_START = 1024 * 1024 * 1024 + STACK_SIZE;
+
+// Bound the stack location in both directions, so we have bounds
+// that do not depend on the direction it grows.
+static Index STACK_LOWER_LIMIT = STACK_START - STACK_SIZE;
+static Index STACK_UPPER_LIMIT = STACK_START + STACK_SIZE;
class EvallingModuleInstance : public ModuleInstanceBase<EvallingGlobalManager, EvallingModuleInstance> {
public:
@@ -151,7 +156,7 @@ public:
// but it should not be read afterwards, doing so would be undefined behavior
void setupEnvironment() {
// prepare scratch memory
- stack.resize(STACK_SIZE);
+ stack.resize(2 * STACK_SIZE);
// tell the module to accept writes up to the stack end
auto total = STACK_START + STACK_SIZE;
memorySize = total / Memory::kPageSize;
@@ -266,11 +271,11 @@ private:
template<typename T>
T* getMemory(Address address) {
// if memory is on the stack, use the stack
- if (address >= STACK_START) {
- Address relative = address - STACK_START;
- if (relative + sizeof(T) > STACK_SIZE) {
+ if (address >= STACK_LOWER_LIMIT) {
+ if (address >= STACK_UPPER_LIMIT) {
throw FailToEvalException("stack usage too high");
}
+ Address relative = address - STACK_LOWER_LIMIT;
// in range, all is good, use the stack
return (T*)(&instance->stack[relative]);
}
diff --git a/test/ctor-eval/stack-direction.wast b/test/ctor-eval/stack-direction.wast
new file mode 100644
index 000000000..ebd6ef3fc
--- /dev/null
+++ b/test/ctor-eval/stack-direction.wast
@@ -0,0 +1,30 @@
+(module
+ (type $0 (func))
+ (import "env" "memory" (memory $1 256 256))
+ (import "env" "STACKTOP" (global $gimport$0 i32))
+ (global $global$0 (mut i32) (get_global $gimport$0))
+ (export "__post_instantiate" (func $0))
+ ;; if the stack goes **down**, this may seem to write to memory we care about
+ (func $0 (; 0 ;) (type $0)
+ (local $0 i32)
+ (i32.store offset=12
+ (tee_local $0
+ (i32.sub
+ (get_global $global$0)
+ (i32.const 16)
+ )
+ )
+ (i32.const 10)
+ )
+ (i32.store offset=12
+ (get_local $0)
+ (i32.add
+ (i32.load offset=12
+ (get_local $0)
+ )
+ (i32.const 1)
+ )
+ )
+ )
+)
+
diff --git a/test/ctor-eval/stack-direction.wast.ctors b/test/ctor-eval/stack-direction.wast.ctors
new file mode 100644
index 000000000..a9d301395
--- /dev/null
+++ b/test/ctor-eval/stack-direction.wast.ctors
@@ -0,0 +1 @@
+__post_instantiate
diff --git a/test/ctor-eval/stack-direction.wast.out b/test/ctor-eval/stack-direction.wast.out
new file mode 100644
index 000000000..4427f36e0
--- /dev/null
+++ b/test/ctor-eval/stack-direction.wast.out
@@ -0,0 +1,2 @@
+(module
+)