| 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,
|
| +]);
|
| +
|
| +})
|
|
|