// 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

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

// Basic tests.

var outOfUint32RangeValue = 1e12;

function assertMemoryIsValid(memory) {
  assertSame(WebAssembly.Memory.prototype, memory.__proto__);
  assertSame(WebAssembly.Memory, memory.constructor);
  assertTrue(memory instanceof Object);
  assertTrue(memory instanceof WebAssembly.Memory);
}

(function TestConstructor() {
  assertTrue(WebAssembly.Memory instanceof Function);
  assertSame(WebAssembly.Memory, WebAssembly.Memory.prototype.constructor);
  assertTrue(WebAssembly.Memory.prototype.grow instanceof Function);
  let desc = Object.getOwnPropertyDescriptor(WebAssembly.Memory.prototype, 'buffer');
  assertTrue(desc.get instanceof Function);
  assertSame(undefined, desc.set);

  assertThrows(() => new WebAssembly.Memory(), TypeError);
  assertThrows(() => new WebAssembly.Memory(1), TypeError);
  assertThrows(() => new WebAssembly.Memory(""), TypeError);

  assertThrows(() => new WebAssembly.Memory({initial: -1}), RangeError);
  assertThrows(() => new WebAssembly.Memory({initial: outOfUint32RangeValue}), RangeError);

  assertThrows(() => new WebAssembly.Memory({initial: 10, maximum: -1}), RangeError);
  assertThrows(() => new WebAssembly.Memory({initial: 10, maximum: outOfUint32RangeValue}), RangeError);
  assertThrows(() => new WebAssembly.Memory({initial: 10, maximum: 9}), RangeError);

  let memory = new WebAssembly.Memory({initial: 1});
  assertMemoryIsValid(memory);
})();

(function TestConstructorWithMaximum() {
  let memory = new WebAssembly.Memory({initial: 1, maximum: 10});
  assertMemoryIsValid(memory);
})();

(function TestInitialIsUndefined() {
  // New memory with initial = undefined, which means initial = 0.
  let memory = new WebAssembly.Memory({initial: undefined});
  assertMemoryIsValid(memory);
})();

(function TestMaximumIsUndefined() {
  // New memory with maximum = undefined, which means maximum = 0.
  let memory = new WebAssembly.Memory({initial: 0, maximum: undefined});
  assertMemoryIsValid(memory);
})();

(function TestMaximumIsReadOnce() {
  var a = true;
  var desc = {initial: 10};
  Object.defineProperty(desc, 'maximum', {get: function() {
    if (a) {
      a = false;
      return 16;
    }
    else {
      // Change the return value on the second call so it throws.
      return -1;
    }
  }});
  let memory = new WebAssembly.Memory(desc);
  assertMemoryIsValid(memory);
})();

(function TestMaximumDoesHasProperty() {
  var hasPropertyWasCalled = false;
  var desc = {initial: 10};
  var proxy = new Proxy({maximum: 16}, {
    has: function(target, name) { hasPropertyWasCalled = true; }
  });
  Object.setPrototypeOf(desc, proxy);
  let memory = new WebAssembly.Memory(desc);
  assertMemoryIsValid(memory);
  assertTrue(hasPropertyWasCalled);
})();

(function TestBuffer() {
  let memory = new WebAssembly.Memory({initial: 1});
  assertTrue(memory.buffer instanceof Object);
  assertTrue(memory.buffer instanceof ArrayBuffer);
  assertThrows(() => {'use strict'; memory.buffer = memory.buffer}, TypeError)
  assertThrows(() => ({__proto__: memory}).buffer, TypeError)
})();

(function TestMemoryGrow() {
  let memory = new WebAssembly.Memory({initial: 1, maximum:30});
  assertEquals(1, memory.grow(9));
  assertTrue(memory.buffer instanceof ArrayBuffer);
  assertTrue(10*kPageSize == memory.buffer.byteLength);
  assertMemoryIsValid(memory);
  assertThrows(() => memory.grow(21));
})();
