1// Copyright 2015 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5(function(global, utils) { 6 7"use strict"; 8 9%CheckIsBootstrapping(); 10 11// ------------------------------------------------------------------- 12// Imports 13 14var GlobalObject = global.Object; 15var MaxSimple; 16var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); 17 18utils.Import(function(from) { 19 MaxSimple = from.MaxSimple; 20}); 21 22// ------------------------------------------------------------------- 23 24 25function CheckSharedIntegerTypedArray(ia) { 26 if (!%IsSharedIntegerTypedArray(ia)) { 27 throw %make_type_error(kNotIntegerSharedTypedArray, ia); 28 } 29} 30 31function CheckSharedInteger32TypedArray(ia) { 32 CheckSharedIntegerTypedArray(ia); 33 if (!%IsSharedInteger32TypedArray(ia)) { 34 throw %make_type_error(kNotInt32SharedTypedArray, ia); 35 } 36} 37 38// https://tc39.github.io/ecmascript_sharedmem/shmem.html#Atomics.ValidateAtomicAccess 39function ValidateIndex(index, length) { 40 var numberIndex = TO_NUMBER(index); 41 var accessIndex = TO_INTEGER(numberIndex); 42 if (numberIndex !== accessIndex) { 43 throw %make_range_error(kInvalidAtomicAccessIndex); 44 } 45 if (accessIndex < 0 || accessIndex >= length) { 46 throw %make_range_error(kInvalidAtomicAccessIndex); 47 } 48 return accessIndex; 49} 50 51//------------------------------------------------------------------- 52 53function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) { 54 CheckSharedIntegerTypedArray(sta); 55 index = ValidateIndex(index, %_TypedArrayGetLength(sta)); 56 oldValue = TO_NUMBER(oldValue); 57 newValue = TO_NUMBER(newValue); 58 return %_AtomicsCompareExchange(sta, index, oldValue, newValue); 59} 60 61function AtomicsAddJS(ia, index, value) { 62 CheckSharedIntegerTypedArray(ia); 63 index = ValidateIndex(index, %_TypedArrayGetLength(ia)); 64 value = TO_NUMBER(value); 65 return %_AtomicsAdd(ia, index, value); 66} 67 68function AtomicsSubJS(ia, index, value) { 69 CheckSharedIntegerTypedArray(ia); 70 index = ValidateIndex(index, %_TypedArrayGetLength(ia)); 71 value = TO_NUMBER(value); 72 return %_AtomicsSub(ia, index, value); 73} 74 75function AtomicsAndJS(ia, index, value) { 76 CheckSharedIntegerTypedArray(ia); 77 index = ValidateIndex(index, %_TypedArrayGetLength(ia)); 78 value = TO_NUMBER(value); 79 return %_AtomicsAnd(ia, index, value); 80} 81 82function AtomicsOrJS(ia, index, value) { 83 CheckSharedIntegerTypedArray(ia); 84 index = ValidateIndex(index, %_TypedArrayGetLength(ia)); 85 value = TO_NUMBER(value); 86 return %_AtomicsOr(ia, index, value); 87} 88 89function AtomicsXorJS(ia, index, value) { 90 CheckSharedIntegerTypedArray(ia); 91 index = ValidateIndex(index, %_TypedArrayGetLength(ia)); 92 value = TO_NUMBER(value); 93 return %_AtomicsXor(ia, index, value); 94} 95 96function AtomicsExchangeJS(ia, index, value) { 97 CheckSharedIntegerTypedArray(ia); 98 index = ValidateIndex(index, %_TypedArrayGetLength(ia)); 99 value = TO_NUMBER(value); 100 return %_AtomicsExchange(ia, index, value); 101} 102 103function AtomicsIsLockFreeJS(size) { 104 return %_AtomicsIsLockFree(size); 105} 106 107function AtomicsWaitJS(ia, index, value, timeout) { 108 CheckSharedInteger32TypedArray(ia); 109 index = ValidateIndex(index, %_TypedArrayGetLength(ia)); 110 if (IS_UNDEFINED(timeout)) { 111 timeout = INFINITY; 112 } else { 113 timeout = TO_NUMBER(timeout); 114 if (NUMBER_IS_NAN(timeout)) { 115 timeout = INFINITY; 116 } else { 117 timeout = MaxSimple(0, timeout); 118 } 119 } 120 return %AtomicsWait(ia, index, value, timeout); 121} 122 123function AtomicsWakeJS(ia, index, count) { 124 CheckSharedInteger32TypedArray(ia); 125 index = ValidateIndex(index, %_TypedArrayGetLength(ia)); 126 count = MaxSimple(0, TO_INTEGER(count)); 127 return %AtomicsWake(ia, index, count); 128} 129 130// ------------------------------------------------------------------- 131 132var Atomics = global.Atomics; 133 134// The Atomics global is defined by the bootstrapper. 135 136%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM); 137 138utils.InstallFunctions(Atomics, DONT_ENUM, [ 139 // TODO(binji): remove the rest of the (non futex) Atomics functions as they 140 // become builtins. 141 "compareExchange", AtomicsCompareExchangeJS, 142 "add", AtomicsAddJS, 143 "sub", AtomicsSubJS, 144 "and", AtomicsAndJS, 145 "or", AtomicsOrJS, 146 "xor", AtomicsXorJS, 147 "exchange", AtomicsExchangeJS, 148 "isLockFree", AtomicsIsLockFreeJS, 149 "wait", AtomicsWaitJS, 150 "wake", AtomicsWakeJS, 151]); 152 153}) 154