| Index: src/js/harmony-atomics.js
 | 
| diff --git a/src/js/harmony-atomics.js b/src/js/harmony-atomics.js
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..daeba3f64ff790ae3d06525237afc132d793e7a3
 | 
| --- /dev/null
 | 
| +++ b/src/js/harmony-atomics.js
 | 
| @@ -0,0 +1,160 @@
 | 
| +// 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 MaxSimple;
 | 
| +var MinSimple;
 | 
| +var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
 | 
| +
 | 
| +utils.Import(function(from) {
 | 
| +  MaxSimple = from.MaxSimple;
 | 
| +  MinSimple = from.MinSimple;
 | 
| +});
 | 
| +
 | 
| +// -------------------------------------------------------------------
 | 
| +
 | 
| +
 | 
| +function CheckSharedIntegerTypedArray(ia) {
 | 
| +  if (!%IsSharedIntegerTypedArray(ia)) {
 | 
| +    throw %make_type_error(kNotIntegerSharedTypedArray, ia);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +function CheckSharedInteger32TypedArray(ia) {
 | 
| +  CheckSharedIntegerTypedArray(ia);
 | 
| +  if (!%IsSharedInteger32TypedArray(ia)) {
 | 
| +    throw %make_type_error(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 %make_range_error(kInvalidAtomicAccessIndex);
 | 
| +  }
 | 
| +  if (accessIndex < 0 || accessIndex >= length) {
 | 
| +    throw %make_range_error(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 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(TO_INTEGER(size));
 | 
| +}
 | 
| +
 | 
| +function AtomicsWaitJS(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 %AtomicsWait(ia, index, value, timeout);
 | 
| +}
 | 
| +
 | 
| +function AtomicsWakeJS(ia, index, count) {
 | 
| +  CheckSharedInteger32TypedArray(ia);
 | 
| +  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
 | 
| +  if (IS_UNDEFINED(count)) {
 | 
| +    count = kMaxUint32;
 | 
| +  } else {
 | 
| +    // Clamp to [0, kMaxUint32].
 | 
| +    count = MinSimple(MaxSimple(0, TO_INTEGER(count)), kMaxUint32);
 | 
| +  }
 | 
| +  return %AtomicsWake(ia, index, count);
 | 
| +}
 | 
| +
 | 
| +// -------------------------------------------------------------------
 | 
| +
 | 
| +var Atomics = global.Atomics;
 | 
| +
 | 
| +// The Atomics global is defined by the bootstrapper.
 | 
| +
 | 
| +%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM);
 | 
| +
 | 
| +utils.InstallFunctions(Atomics, DONT_ENUM, [
 | 
| +  // TODO(binji): remove the rest of the (non futex) Atomics functions as they
 | 
| +  // become builtins.
 | 
| +  "compareExchange", AtomicsCompareExchangeJS,
 | 
| +  "add", AtomicsAddJS,
 | 
| +  "sub", AtomicsSubJS,
 | 
| +  "and", AtomicsAndJS,
 | 
| +  "or", AtomicsOrJS,
 | 
| +  "xor", AtomicsXorJS,
 | 
| +  "exchange", AtomicsExchangeJS,
 | 
| +  "isLockFree", AtomicsIsLockFreeJS,
 | 
| +  "wait", AtomicsWaitJS,
 | 
| +  "wake", AtomicsWakeJS,
 | 
| +]);
 | 
| +
 | 
| +})
 | 
| 
 |