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

(function(global, utils) {

"use strict";

%CheckIsBootstrapping();

// -------------------------------------------------------------------
// Imports

var GlobalObject = global.Object;
var MakeRangeError;
var MakeTypeError;
var MaxSimple;
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");

utils.Import(function(from) {
  MakeTypeError = from.MakeTypeError;
  MakeRangeError = from.MakeRangeError;
  MaxSimple = from.MaxSimple;
});

// -------------------------------------------------------------------


function CheckSharedIntegerTypedArray(ia) {
  if (!%IsSharedIntegerTypedArray(ia)) {
    throw MakeTypeError(kNotIntegerSharedTypedArray, ia);
  }
}

function CheckSharedInteger32TypedArray(ia) {
  CheckSharedIntegerTypedArray(ia);
  if (!%IsSharedInteger32TypedArray(ia)) {
    throw MakeTypeError(kNotInt32SharedTypedArray, ia);
  }
}

// https://tc39.github.io/ecmascript_sharedmem/shmem.html#Atomics.ValidateAtomicAccess
function ValidateIndex(index, length) {
  var numberIndex = TO_NUMBER(index);
  var accessIndex = TO_INTEGER(numberIndex);
  if (numberIndex !== accessIndex) {
    throw MakeRangeError(kInvalidAtomicAccessIndex);
  }
  if (accessIndex < 0 || accessIndex >= length) {
    throw MakeRangeError(kInvalidAtomicAccessIndex);
  }
  return accessIndex;
}

//-------------------------------------------------------------------

function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) {
  CheckSharedIntegerTypedArray(sta);
  index = ValidateIndex(index, %_TypedArrayGetLength(sta));
  oldValue = TO_NUMBER(oldValue);
  newValue = TO_NUMBER(newValue);
  return %_AtomicsCompareExchange(sta, index, oldValue, newValue);
}

function AtomicsLoadJS(sta, index) {
  CheckSharedIntegerTypedArray(sta);
  index = ValidateIndex(index, %_TypedArrayGetLength(sta));
  return %_AtomicsLoad(sta, index);
}

function AtomicsStoreJS(sta, index, value) {
  CheckSharedIntegerTypedArray(sta);
  index = ValidateIndex(index, %_TypedArrayGetLength(sta));
  value = TO_NUMBER(value);
  return %_AtomicsStore(sta, index, value);
}

function AtomicsAddJS(ia, index, value) {
  CheckSharedIntegerTypedArray(ia);
  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
  value = TO_NUMBER(value);
  return %_AtomicsAdd(ia, index, value);
}

function AtomicsSubJS(ia, index, value) {
  CheckSharedIntegerTypedArray(ia);
  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
  value = TO_NUMBER(value);
  return %_AtomicsSub(ia, index, value);
}

function AtomicsAndJS(ia, index, value) {
  CheckSharedIntegerTypedArray(ia);
  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
  value = TO_NUMBER(value);
  return %_AtomicsAnd(ia, index, value);
}

function AtomicsOrJS(ia, index, value) {
  CheckSharedIntegerTypedArray(ia);
  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
  value = TO_NUMBER(value);
  return %_AtomicsOr(ia, index, value);
}

function AtomicsXorJS(ia, index, value) {
  CheckSharedIntegerTypedArray(ia);
  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
  value = TO_NUMBER(value);
  return %_AtomicsXor(ia, index, value);
}

function AtomicsExchangeJS(ia, index, value) {
  CheckSharedIntegerTypedArray(ia);
  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
  value = TO_NUMBER(value);
  return %_AtomicsExchange(ia, index, value);
}

function AtomicsIsLockFreeJS(size) {
  return %_AtomicsIsLockFree(size);
}

// Futexes

function AtomicsFutexWaitJS(ia, index, value, timeout) {
  CheckSharedInteger32TypedArray(ia);
  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
  if (IS_UNDEFINED(timeout)) {
    timeout = INFINITY;
  } else {
    timeout = TO_NUMBER(timeout);
    if (NUMBER_IS_NAN(timeout)) {
      timeout = INFINITY;
    } else {
      timeout = MaxSimple(0, timeout);
    }
  }
  return %AtomicsFutexWait(ia, index, value, timeout);
}

function AtomicsFutexWakeJS(ia, index, count) {
  CheckSharedInteger32TypedArray(ia);
  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
  count = MaxSimple(0, TO_INTEGER(count));
  return %AtomicsFutexWake(ia, index, count);
}

function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) {
  CheckSharedInteger32TypedArray(ia);
  index1 = ValidateIndex(index1, %_TypedArrayGetLength(ia));
  count = MaxSimple(0, TO_INTEGER(count));
  value = TO_INT32(value);
  index2 = ValidateIndex(index2, %_TypedArrayGetLength(ia));
  if (index1 < 0 || index1 >= %_TypedArrayGetLength(ia) ||
      index2 < 0 || index2 >= %_TypedArrayGetLength(ia)) {
    return UNDEFINED;
  }
  return %AtomicsFutexWakeOrRequeue(ia, index1, count, value, index2);
}

// -------------------------------------------------------------------

function AtomicsConstructor() {}

var Atomics = new AtomicsConstructor();

%InternalSetPrototype(Atomics, GlobalObject.prototype);
%AddNamedProperty(global, "Atomics", Atomics, DONT_ENUM);
%FunctionSetInstanceClassName(AtomicsConstructor, 'Atomics');

%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM);

// These must match the values in src/futex-emulation.h
utils.InstallConstants(Atomics, [
  "OK", 0,
  "NOTEQUAL", -1,
  "TIMEDOUT", -2,
]);

utils.InstallFunctions(Atomics, DONT_ENUM, [
  "compareExchange", AtomicsCompareExchangeJS,
  "load", AtomicsLoadJS,
  "store", AtomicsStoreJS,
  "add", AtomicsAddJS,
  "sub", AtomicsSubJS,
  "and", AtomicsAndJS,
  "or", AtomicsOrJS,
  "xor", AtomicsXorJS,
  "exchange", AtomicsExchangeJS,
  "isLockFree", AtomicsIsLockFreeJS,
  "futexWait", AtomicsFutexWaitJS,
  "futexWake", AtomicsFutexWakeJS,
  "futexWakeOrRequeue", AtomicsFutexWakeOrRequeueJS,
]);

})
