// 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 toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); utils.Import(function(from) { MaxSimple = from.MaxSimple; }); // ------------------------------------------------------------------- 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(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)); count = MaxSimple(0, TO_INTEGER(count)); 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, ]); })