Index: test/mjsunit/wasm/grow-memory.js |
diff --git a/test/mjsunit/wasm/grow-memory.js b/test/mjsunit/wasm/grow-memory.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c6ffbd128242f3f284af127c0b12d0f6fc557444 |
--- /dev/null |
+++ b/test/mjsunit/wasm/grow-memory.js |
@@ -0,0 +1,200 @@ |
+// Copyright 2016 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Flags: --expose-wasm --expose-gc --stress-compaction |
+ |
+load("test/mjsunit/wasm/wasm-constants.js"); |
+load("test/mjsunit/wasm/wasm-module-builder.js"); |
+ |
+function genGrowMemoryBuilder() { |
+ var builder = new WasmModuleBuilder(); |
+ builder.addFunction("grow_memory", kSig_i_i) |
+ .addBody([kExprGetLocal, 0, kExprGrowMemory]) |
+ .exportFunc(); |
+ builder.addFunction("load", kSig_i_i) |
+ .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) |
+ .exportFunc(); |
+ builder.addFunction("store", kSig_i_ii) |
+ .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0]) |
+ .exportFunc(); |
+ return builder; |
+} |
+ |
+function testGrowMemoryReadWrite() { |
+ var builder = genGrowMemoryBuilder(); |
+ builder.addMemory(1, 1, false); |
+ var module = builder.instantiate(); |
+ var offset; |
+ function peek() { return module.exports.load(offset); } |
ahaas
2016/06/24 11:10:15
why don't you pass in offset as a parameter?
gdeepti
2016/06/25 00:28:42
Because the assertTraps function in wasm-constants
|
+ function poke(value) { return module.exports.store(offset, value); } |
+ function growMem(pages) { return module.exports.grow_memory(pages); } |
+ |
+ for(offset = 0; offset < 65533; offset++) { |
ahaas
2016/06/24 11:10:15
could you use a named constant here instead of 655
gdeepti
2016/06/25 00:28:42
Done.
|
+ poke(20); |
+ assertEquals(peek(), 20); |
+ } |
+ for (offset = 65534; offset < 66538; offset++) { |
ahaas
2016/06/24 11:10:15
same here
gdeepti
2016/06/25 00:28:41
Done.
|
+ assertTraps(kTrapMemOutOfBounds, poke); |
+ assertTraps(kTrapMemOutOfBounds, peek); |
+ } |
+ |
+ try { |
+ assertEquals(growMem(3), 1); |
+ } catch (e) { |
+ assertEquals("object", typeof e); |
+ assertEquals(e.message, "failed to allocate memory"); |
+ return; |
+ } |
+ |
+ for (offset = 65534; offset < 262141; offset++) { |
ahaas
2016/06/24 11:10:15
same here
gdeepti
2016/06/25 00:28:42
Done.
|
+ poke(20); |
+ assertEquals(peek(), 20); |
+ } |
+ for (offset = 262142; offset < 262145; offset++) { |
ahaas
2016/06/24 11:10:15
same here
gdeepti
2016/06/25 00:28:41
Done.
|
+ assertTraps(kTrapMemOutOfBounds, poke); |
+ assertTraps(kTrapMemOutOfBounds, peek); |
+ } |
+ |
+ try { |
+ assertEquals(growMem(15), 4); |
+ } catch (e) { |
+ assertEquals("object", typeof e); |
+ assertEquals(e.message, "failed to allocate memory"); |
+ return; |
+ } |
+ |
+ for (offset = 262142; offset < 262148; offset++) { |
+ poke(20); |
+ assertEquals(peek(), 20); |
+ } |
+ for (offset = 1245184; offset < 1245188; offset++) { |
ahaas
2016/06/24 11:10:15
could you add a test for the upper bound?, e.g. by
gdeepti
2016/06/25 00:28:42
Done.
|
+ assertTraps(kTrapMemOutOfBounds, poke); |
+ assertTraps(kTrapMemOutOfBounds, peek); |
+ } |
+} |
+ |
+testGrowMemoryReadWrite(); |
+ |
+function testGrowMemoryZeroInitialSize() { |
+ var builder = genGrowMemoryBuilder(); |
+ var module = builder.instantiate(); |
+ var offset; |
+ function peek() { return module.exports.load(offset); } |
+ function poke(value) { return module.exports.store(offset, value); } |
+ function growMem(pages) { return module.exports.grow_memory(pages); } |
+ |
+ assertTraps(kTrapMemOutOfBounds, peek); |
+ assertTraps(kTrapMemOutOfBounds, poke); |
+ |
+ try { |
+ assertEquals(growMem(1), 0); |
+ } catch (e) { |
+ assertEquals("object", typeof e); |
+ assertEquals(e.message, "failed to allocate memory"); |
+ return; |
+ } |
+ |
+ for(offset = 0; offset <=65533; offset++) { |
+ poke(20); |
+ assertEquals(peek(), 20); |
+ } |
+ |
+ //TODO(gdeepti): Fix tests with correct write boundaries |
+ //when runtime function is fixed. |
+ for(offset = 65536; offset <= 65539; offset++) { |
+ assertTraps(kTrapMemOutOfBounds, peek); |
+ } |
+} |
+ |
+testGrowMemoryZeroInitialSize(); |
+ |
+function testGrowMemoryTrapMaxPagesZeroInitialMemory() { |
+ var builder = genGrowMemoryBuilder(); |
+ var module = builder.instantiate(); |
+ var maxPages = 16385; |
+ function growMem() { return module.exports.grow_memory(maxPages); } |
+ try { |
+ growMem(); |
+ } catch (e) { |
+ assertEquals("object", typeof e); |
+ if (e.message === "failed to allocate memory" || |
ahaas
2016/06/24 11:10:15
How can both of these messages be possible?
gdeepti
2016/06/25 00:28:42
Left over from when I was trying to catch windows
|
+ e.message === "memory access out of bounds") { |
+ return; |
+ } |
+ } |
+} |
+ |
+testGrowMemoryTrapMaxPagesZeroInitialMemory(); |
+ |
+function testGrowMemoryTrapMaxPages() { |
+ var builder = genGrowMemoryBuilder(); |
+ builder.addMemory(1, 1, false); |
+ var module = builder.instantiate(); |
+ var maxPages = 16384; |
+ function growMem() { return module.exports.grow_memory(maxPages); } |
+ try { |
+ growMem(); |
+ } catch (e) { |
+ assertEquals("object", typeof e); |
+ if (e.message === "failed to allocate memory" || |
+ e.message === "memory access out of bounds") { |
+ return; |
+ } |
+ } |
+} |
+ |
+testGrowMemoryTrapMaxPages(); |
+ |
+function testGrowMemoryOobThrows() { |
+ var builder = genGrowMemoryBuilder(); |
+ builder.addMemory(1, 1, false); |
+ builder.addFunction("geti", kSig_i_ii) |
+ .addBody([ |
+ kExprGetLocal, 0, |
+ kExprGetLocal, 1, |
+ kExprI32LoadMem, 0, 0, |
+ kExprI32StoreMem, 0, 0 |
+ ]) |
+ .exportFunc(); |
+ |
+ var module = builder.instantiate(); |
+ var offset; |
+ |
+ function read() { return module.exports.geti(0, offset); } |
+ function write() { return module.exports.geti(offset, 0); } |
+ |
+ for (offset = 0; offset < 65533; offset++) { |
+ assertEquals(0, read()); |
ahaas
2016/06/24 11:10:15
I don't understand this test. It seems to be eithe
gdeepti
2016/06/25 00:28:42
I added this test as a sanity check for oob with g
|
+ assertEquals(0, write()); |
+ } |
+ |
+ for (offset = 65534; offset < 66536; offset++) { |
+ assertTraps(kTrapMemOutOfBounds, read); |
+ assertTraps(kTrapMemOutOfBounds, write); |
+ } |
+ |
+ function resizeMem() { return module.exports.grow_memory(2); } |
+ |
+ try { |
+ assertEquals(1, resizeMem()); |
+ } catch (e) { |
+ assertEquals("object", typeof e); |
+ assertEquals(e.message, "failed to allocate memory"); |
+ return; |
+ } |
+ |
+ |
+ for (offset = 0; offset < 196605; offset++) { |
+ assertEquals(0, read()); |
+ assertEquals(0, write()); |
+ } |
+ |
+ for (offset = 196605; offset < 196610; offset++) { |
+ assertTraps(kTrapMemOutOfBounds, read); |
+ assertTraps(kTrapMemOutOfBounds, write); |
+ } |
+ |
+} |
+ |
+testGrowMemoryOobThrows(); |