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

const stdlib = {
  Math: Math,
  Int8Array: Int8Array,
  Int16Array: Int16Array,
  Int32Array: Int32Array,
  Uint8Array: Uint8Array,
  Uint16Array: Uint16Array,
  Uint32Array: Uint32Array,
  Float32Array: Float32Array,
  Float64Array: Float64Array,
};

const buffer = new ArrayBuffer(65536);
const BASE = 1000000000;

const OOB_INDEXES = [
  buffer.byteLength,
  buffer.byteLength + 1,
  buffer.byteLength + 2,
  buffer.byteLength + 3,
  buffer.byteLength + 4,
  buffer.byteLength + 5,
  buffer.byteLength + 6,
  buffer.byteLength + 7,
  buffer.byteLength + 8,
  buffer.byteLength + 9,
  buffer.byteLength + 10,
  0x80000000,
  0x80000004,
  0xF0000000,
  0xFFFFFFFF,
  0xFFFFFFFE,
  -1, -2, -3, -4, -5, -6, -7, -8
];

function resetBuffer() {
  var view = new Int32Array(buffer);
  for (var i = 0; i < view.length; i++) {
    view[i] = BASE | (i << 2);
  }
}
resetBuffer();


function checkView(view, load, shift) {
  for (var i = 0; i < 300; i++) {
    assertEquals(view[i >> shift], load(i));
  }
}

function RunThreeWayTest(asmfunc, expect) {
  var asm_source = asmfunc.toString();
  var nonasm_source = asm_source.replace(new RegExp("use asm"), "");

  var js_module = eval("(" + nonasm_source + ")")(stdlib, {}, buffer);
  print("Testing " + asmfunc.name + " (js)...");
  expect(js_module);

  print("Testing " + asmfunc.name + " (asm.js)...");
  var asm_module = asmfunc(stdlib, {}, buffer);
  expect(asm_module);

  print("Testing " + asmfunc.name + " (wasm)...");
  var wasm_module = Wasm.instantiateModuleFromAsm(asm_source, null, buffer);
  expect(wasm_module);
}

function LoadAt_i32(stdlib, foreign, buffer) {
  "use asm";
  var HEAP32 = new stdlib.Int32Array(buffer);
  function load(a) {
    a = a | 0;
    return HEAP32[a >> 2] | 0;
  }
  return {load: load};
}

RunThreeWayTest(LoadAt_i32, function(module) {
  var load = module.load;
  assertEquals(BASE, load(0));
  assertEquals(BASE | 0x30, load(0x30));
  assertEquals(BASE | 0x704, load(0x704));
  assertEquals(BASE | 0x704, load(0x705));
  assertEquals(BASE | 0x704, load(0x706));
  assertEquals(BASE | 0x704, load(0x707));

  var length = buffer.byteLength;
  assertEquals(BASE | (length - 4), load(length - 4));
  assertEquals(BASE | (length - 4), load(length - 4 + 1));
  assertEquals(BASE | (length - 4), load(length - 4 + 2));
  assertEquals(BASE | (length - 4), load(length - 4 + 3));

  for (index of OOB_INDEXES) assertEquals(0, load(index));
  checkView(new Int32Array(buffer), load, 2);
});

function LoadAt_i16(stdlib, foreign, buffer) {
  "use asm";
  var HEAP16 = new stdlib.Int16Array(buffer);
  function load(a) {
    a = a | 0;
    return HEAP16[a >> 1] | 0;
  }
  return {load: load};
}

RunThreeWayTest(LoadAt_i16, function(module) {
  var load = module.load;
  var LOWER = (BASE << 16) >> 16;
  var UPPER = BASE >> 16;
  assertEquals(LOWER, load(0));
  assertEquals(UPPER, load(2));

  assertEquals(LOWER | 0x30, load(0x30));
  assertEquals(UPPER, load(0x32));

  assertEquals(LOWER | 0x504, load(0x504));
  assertEquals(LOWER | 0x504, load(0x505));

  assertEquals(UPPER, load(0x706));
  assertEquals(UPPER, load(0x707));

  var length = buffer.byteLength;
  assertEquals(LOWER | (length - 4), load(length - 4));
  assertEquals(LOWER | (length - 4), load(length - 4 + 1));
  assertEquals(UPPER, load(length - 4 + 2));
  assertEquals(UPPER, load(length - 4 + 3));

  for (index of OOB_INDEXES) assertEquals(0, load(index));
  checkView(new Int16Array(buffer), load, 1);
});

function LoadAt_u16(stdlib, foreign, buffer) {
  "use asm";
  var HEAP16 = new stdlib.Uint16Array(buffer);
  function load(a) {
    a = a | 0;
    return HEAP16[a >> 1] | 0;
  }
  return {load: load};
}

RunThreeWayTest(LoadAt_u16, function(module) {
  var load = module.load;
  for (index of OOB_INDEXES) assertEquals(0, load(index));
  checkView(new Uint16Array(buffer), load, 1);
});

function LoadAt_i8(stdlib, foreign, buffer) {
  "use asm";
  var HEAP8 = new stdlib.Int8Array(buffer);
  function load(a) {
    a = a | 0;
    return HEAP8[a >> 0] | 0;
  }
  return {load: load};
}

RunThreeWayTest(LoadAt_i8, function(module) {
  var load = module.load;
  for (index of OOB_INDEXES) assertEquals(0, load(index));
  checkView(new Int8Array(buffer), load, 0);
});

function LoadAt_u8(stdlib, foreign, buffer) {
  "use asm";
  var HEAP8 = new stdlib.Uint8Array(buffer);
  function load(a) {
    a = a | 0;
    return HEAP8[a >> 0] | 0;
  }
  return {load: load};
}

RunThreeWayTest(LoadAt_u8, function(module) {
  var load = module.load;
  for (index of OOB_INDEXES) assertEquals(0, load(index));
  checkView(new Uint8Array(buffer), load, 0);
});


function LoadAt_u32(stdlib, foreign, buffer) {
  "use asm";
  var HEAP32 = new stdlib.Uint32Array(buffer);
  function load(a) {
    a = a | 0;
    return +(HEAP32[a >> 2] >>> 0);
  }
  return {load: load};
}

RunThreeWayTest(LoadAt_u32, function(module) {
  var load = module.load;
  for (index of OOB_INDEXES) assertEquals(0, load(index));
  checkView(new Uint32Array(buffer), load, 2);
});

function LoadAt_f32(stdlib, foreign, buffer) {
  "use asm";
  var HEAP32 = new stdlib.Float32Array(buffer);
  var fround = stdlib.Math.fround;
  function load(a) {
    a = a | 0;
    return fround(HEAP32[a >> 2]);
  }
  return {load: load};
}

RunThreeWayTest(LoadAt_f32, function(module) {
  var load = module.load;
  for (index of OOB_INDEXES) assertEquals(NaN, load(index));
  checkView(new Float32Array(buffer), load, 2);
});

function LoadAt_f64(stdlib, foreign, buffer) {
  "use asm";
  var HEAP64 = new stdlib.Float64Array(buffer);
  function load(a) {
    a = a | 0;
    return +HEAP64[a >> 3];
  }
  return {load: load};
}

RunThreeWayTest(LoadAt_f64, function(module) {
  var load = module.load;
  for (index of OOB_INDEXES) assertEquals(NaN, load(index));
  checkView(new Float64Array(buffer), load, 3);
});

// TODO(titzer): constant heap indexes
// TODO(titzer): heap accesses with offsets and arithmetic
// TODO(titzer): [i >> K] where K is greater than log(size)
