// Copyright 2015 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"); var kMemSize = 4096; function genModule(memory) { var kBodySize = 27; var kNameMainOffset = 28 + kBodySize + 1; var data = bytes( kDeclMemory, 12, 12, 1, // memory // -- signatures kDeclSignatures, 1, 1, kAstI32, kAstI32, // int->int // -- main function kDeclFunctions, 1, kDeclFunctionLocals | kDeclFunctionName | kDeclFunctionExport, 0, 0, kNameMainOffset, 0, 0, 0, // name offset 1, 0, // local int32 count 0, 0, // local int64 count 0, 0, // local float32 count 0, 0, // local float64 count kBodySize, 0, // code size // main body: while(i) { if(mem[i]) return -1; i -= 4; } return 0; kExprBlock,2, kExprLoop,1, kExprIf, kExprGetLocal,0, kExprBr, 0, kExprIfElse, kExprI32LoadMem,0,kExprGetLocal,0, kExprBr,2, kExprI8Const, 255, kExprSetLocal,0, kExprI32Sub,kExprGetLocal,0,kExprI8Const,4, kExprI8Const,0, // names kDeclEnd, 'm', 'a', 'i', 'n', 0 // -- ); return _WASMEXP_.instantiateModule(data, null, memory); } function testPokeMemory() { var module = genModule(null); var buffer = module.memory; assertEquals(kMemSize, buffer.byteLength); var array = new Int8Array(buffer); assertEquals(kMemSize, array.length); for (var i = 0; i < kMemSize; i++) { assertEquals(0, array[i]); } for (var i = 0; i < 10; i++) { assertEquals(0, module.main(kMemSize - 4)); array[kMemSize/2 + i] = 1; assertEquals(0, module.main(kMemSize/2 - 4)); assertEquals(-1, module.main(kMemSize - 4)); array[kMemSize/2 + i] = 0; assertEquals(0, module.main(kMemSize - 4)); } } testPokeMemory(); function testSurvivalAcrossGc() { var checker = genModule(null).main; for (var i = 0; i < 5; i++) { print("gc run ", i); assertEquals(0, checker(kMemSize - 4)); gc(); } } testSurvivalAcrossGc(); testSurvivalAcrossGc(); testSurvivalAcrossGc(); testSurvivalAcrossGc(); function testPokeOuterMemory() { var buffer = new ArrayBuffer(kMemSize); var module = genModule(buffer); assertEquals(kMemSize, buffer.byteLength); var array = new Int8Array(buffer); assertEquals(kMemSize, array.length); for (var i = 0; i < kMemSize; i++) { assertEquals(0, array[i]); } for (var i = 0; i < 10; i++) { assertEquals(0, module.main(kMemSize - 4)); array[kMemSize/2 + i] = 1; assertEquals(0, module.main(kMemSize/2 - 4)); assertEquals(-1, module.main(kMemSize - 4)); array[kMemSize/2 + i] = 0; assertEquals(0, module.main(kMemSize - 4)); } } testPokeOuterMemory(); function testOuterMemorySurvivalAcrossGc() { var buffer = new ArrayBuffer(kMemSize); var checker = genModule(buffer).main; for (var i = 0; i < 5; i++) { print("gc run ", i); assertEquals(0, checker(kMemSize - 4)); gc(); } } testOuterMemorySurvivalAcrossGc(); testOuterMemorySurvivalAcrossGc(); testOuterMemorySurvivalAcrossGc(); testOuterMemorySurvivalAcrossGc(); function testOOBThrows() { var kBodySize = 8; var kNameMainOffset = 29 + kBodySize + 1; var data = bytes( kDeclMemory, 12, 12, 1, // memory = 4KB // -- signatures kDeclSignatures, 1, 2, kAstI32, kAstI32, kAstI32, // int->int // -- main function kDeclFunctions, 1, kDeclFunctionLocals | kDeclFunctionName | kDeclFunctionExport, 0, 0, kNameMainOffset, 0, 0, 0, // name offset 1, 0, // local int32 count 0, 0, // local int64 count 0, 0, // local float32 count 0, 0, // local float64 count kBodySize, 0, // code size // geti: return mem[a] = mem[b] kExprI32StoreMem, 0, kExprGetLocal, 0, kExprI32LoadMem, 0, kExprGetLocal, 1, // names kDeclEnd, 'g','e','t','i', 0 // -- ); var memory = null; var module = _WASMEXP_.instantiateModule(data, null, memory); var offset; function read() { return module.geti(0, offset); } function write() { return module.geti(offset, 0); } for (offset = 0; offset < 4092; offset++) { assertEquals(0, read()); assertEquals(0, write()); } for (offset = 4093; offset < 4124; offset++) { assertTraps(kTrapMemOutOfBounds, read); assertTraps(kTrapMemOutOfBounds, write); } } testOOBThrows();