// 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 --allow-natives-syntax

load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");

var kMemSize = 65536;

function genModule(memory) {
  var builder = new WasmModuleBuilder();

  builder.addImportedMemory("", "memory", 1);
  builder.exportMemoryAs("memory");
  builder.addFunction("main", kSig_i_i)
    .addBody([
      // main body: while(i) { if(mem[i]) return -1; i -= 4; } return 0;
      // TODO(titzer): this manual bytecode has a copy of test-run-wasm.cc
      /**/ kExprLoop, kWasmStmt,           // --
      /*  */ kExprGetLocal, 0,             // --
      /*  */ kExprIf, kWasmStmt,           // --
      /*    */ kExprGetLocal, 0,           // --
      /*    */ kExprI32LoadMem, 0, 0,      // --
      /*    */ kExprIf, kWasmStmt,         // --
      /*      */ kExprI32Const, 127,       // --
      /*      */ kExprReturn,              // --
      /*      */ kExprEnd,                 // --
      /*    */ kExprGetLocal, 0,           // --
      /*    */ kExprI32Const, 4,           // --
      /*    */ kExprI32Sub,                // --
      /*    */ kExprSetLocal, 0,           // --
      /*    */ kExprBr, 1,                 // --
      /*    */ kExprEnd,                   // --
      /*  */ kExprEnd,                     // --
      /**/ kExprI32Const, 0                // --
    ])
    .exportFunc();
  var module = builder.instantiate({"": {memory:memory}});
  assertTrue(module.exports.memory instanceof WebAssembly.Memory);
  if (memory != null) assertEquals(memory.buffer, module.exports.memory.buffer);
  return module;
}

function testPokeMemory() {
  print("testPokeMemory");
  var module = genModule(new WebAssembly.Memory({initial: 1}));
  var buffer = module.exports.memory.buffer;
  var main = module.exports.main;
  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, main(kMemSize - 4));

    array[kMemSize/2 + i] = 1;
    assertEquals(0, main(kMemSize/2 - 4));
    assertEquals(-1, main(kMemSize - 4));

    array[kMemSize/2 + i] = 0;
    assertEquals(0, main(kMemSize - 4));
  }
}

testPokeMemory();

function genAndGetMain(buffer) {
  return genModule(buffer).exports.main;  // to prevent intermediates living
}

function testSurvivalAcrossGc() {
  var checker = genAndGetMain(new WebAssembly.Memory({initial: 1}));
  for (var i = 0; i < 3; i++) {
    print("gc run ", i);
    assertEquals(0, checker(kMemSize - 4));
    gc();
  }
}

testSurvivalAcrossGc();
testSurvivalAcrossGc();
testSurvivalAcrossGc();
testSurvivalAcrossGc();


function testPokeOuterMemory() {
  print("testPokeOuterMemory");
  var buffer = new WebAssembly.Memory({initial: kMemSize / kPageSize});
  var module = genModule(buffer);
  var main = module.exports.main;
  assertEquals(kMemSize, buffer.buffer.byteLength);

  var array = new Int8Array(buffer.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, main(kMemSize - 4));

    array[kMemSize/2 + i] = 1;
    assertEquals(0, main(kMemSize/2 - 4));
    assertEquals(-1, main(kMemSize - 4));

    array[kMemSize/2 + i] = 0;
    assertEquals(0, main(kMemSize - 4));
  }
}

testPokeOuterMemory();

function testOuterMemorySurvivalAcrossGc() {
  var buffer = new WebAssembly.Memory({initial: kMemSize / kPageSize});
  var checker = genAndGetMain(buffer);
  for (var i = 0; i < 3; i++) {
    print("gc run ", i);
    assertEquals(0, checker(kMemSize - 4));
    gc();
  }
}

testOuterMemorySurvivalAcrossGc();
testOuterMemorySurvivalAcrossGc();
testOuterMemorySurvivalAcrossGc();
testOuterMemorySurvivalAcrossGc();


function testOOBThrows() {
  var builder = new WasmModuleBuilder();

  builder.addMemory(1, 1, true);
  builder.addFunction("geti", kSig_i_ii)
    .addBody([
      kExprGetLocal, 0,
      kExprGetLocal, 1,
      kExprI32LoadMem, 0, 0,
      kExprI32StoreMem, 0, 0,
      kExprGetLocal, 1,
      kExprI32LoadMem, 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());
    assertEquals(0, write());
  }


  for (offset = 65534; offset < 66536; offset++) {
    const trap_count = %GetWasmRecoveredTrapCount();
    assertTraps(kTrapMemOutOfBounds, read);
    assertTraps(kTrapMemOutOfBounds, write);
    if (%IsWasmTrapHandlerEnabled()) {
      assertEquals(trap_count + 2, %GetWasmRecoveredTrapCount());
    }
  }
}

testOOBThrows();

function testAddressSpaceLimit() {
  // 1TiB, see wasm-memory.h
  const kMaxAddressSpace = 1 * 1024 * 1024 * 1024 * 1024;
  const kAddressSpacePerMemory = 8 * 1024 * 1024 * 1024;

  try {
    let memories = [];
    let address_space = 0;
    while (address_space <= kMaxAddressSpace + 1) {
      memories.push(new WebAssembly.Memory({initial: 1}));
      address_space += kAddressSpacePerMemory;
    }
  } catch (e) {
    assertTrue(e instanceof RangeError);
    return;
  }
  failWithMessage("allocated too much memory");
}

if(%IsWasmTrapHandlerEnabled()) {
  testAddressSpaceLimit();
}
