diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-06 09:08:21 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-06 09:08:21 -0800 |
commit | 38b6e18b5b563ee235f426d695a89c20cb08ada5 (patch) | |
tree | faf22c0d978f783e359244c2b961385551db4ec6 | |
parent | 034596930c9d4ca3e771e78e03e06efc026fadff (diff) | |
download | binaryen-38b6e18b5b563ee235f426d695a89c20cb08ada5.tar.gz binaryen-38b6e18b5b563ee235f426d695a89c20cb08ada5.tar.bz2 binaryen-38b6e18b5b563ee235f426d695a89c20cb08ada5.zip |
host ops
-rw-r--r-- | src/wasm-interpreter.h | 12 | ||||
-rw-r--r-- | src/wasm-js.cpp | 4 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 9 | ||||
-rw-r--r-- | src/wasm-shell.cpp | 7 |
4 files changed, 28 insertions, 4 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 0ca4d9674..5279e8a35 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -43,6 +43,7 @@ public: virtual Literal callImport(Import* import, LiteralList& arguments) = 0; virtual Literal load(Load* load, size_t addr) = 0; virtual void store(Store* store, size_t addr, Literal value) = 0; + virtual void growMemory(size_t oldSize, size_t newSize) = 0; virtual void trap() = 0; }; @@ -634,11 +635,18 @@ public: } Flow visitHost(Host *curr) override { NOTE_ENTER("Host"); - switch (curr->op) { case PageSize: return Literal(64*1024); case MemorySize: return Literal(instance.memorySize); - case GrowMemory: abort(); + case GrowMemory: { + Flow flow = visit(curr->operands[0]); + if (flow.breaking()) return flow; + size_t newSize = flow.value.getInteger(); + if (newSize > instance.wasm.memory.max) trap(); + instance.externalInterface->growMemory(instance.memorySize, newSize); + instance.memorySize = newSize; + return Literal(); + } case HasFeature: { IString id = curr->nameOperand; if (id == WASM) return Literal(1); diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index 44c5cb099..ddb31b33d 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -173,6 +173,10 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm(char *input) { } } + void growMemory(size_t oldSize, size_t newSize) override { + abort(); + } + void trap() override { EM_ASM({ abort("wasm trap!"); diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index b81800ad2..58f316075 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -500,6 +500,7 @@ public: } case 'g': { if (str[1] == 'e') return makeGetLocal(s); + if (str[1] == 'r') return makeHost(s, HostOp::GrowMemory); abort_on(str); } case 'h': { @@ -515,10 +516,18 @@ public: if (str[1] == 'o') return makeLoop(s); abort_on(str); } + case 'm': { + if (str[1] == 'e') return makeHost(s, HostOp::MemorySize); + abort_on(str); + } case 'n': { if (str[1] == 'o') return allocator.alloc<Nop>(); abort_on(str); } + case 'p': { + if (str[1] == 'a') return makeHost(s, HostOp::PageSize); + abort_on(str); + } case 's': { if (str[1] == 'e') return makeSetLocal(s); abort_on(str); diff --git a/src/wasm-shell.cpp b/src/wasm-shell.cpp index c37ba79a3..5f9fafd8f 100644 --- a/src/wasm-shell.cpp +++ b/src/wasm-shell.cpp @@ -24,13 +24,11 @@ IString ASSERT_RETURN("assert_return"), struct ShellExternalInterface : ModuleInstance::ExternalInterface { char *memory; - size_t memorySize; ShellExternalInterface() : memory(nullptr) {} void init(Module& wasm) override { memory = new char[wasm.memory.initial]; - memorySize = wasm.memory.initial; // apply memory segments for (auto segment : wasm.memory.segments) { memcpy(memory + segment.offset, segment.data, segment.size); @@ -104,6 +102,11 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface { } } + void growMemory(size_t oldSize, size_t newSize) override { + delete memory; + memory = new char[newSize]; + } + jmp_buf trapState; void trap() override { |