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 MakeTypeError; 16var MaxSimple; 17var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); 18 19utils.Import(function(from) { 20 MakeTypeError = from.MakeTypeError; 21 MaxSimple = from.MaxSimple; 22}); 23 24// ------------------------------------------------------------------- 25 26 27function CheckSharedIntegerTypedArray(ia) { 28 if (!%IsSharedIntegerTypedArray(ia)) { 29 throw MakeTypeError(kNotIntegerSharedTypedArray, ia); 30 } 31} 32 33function CheckSharedInteger32TypedArray(ia) { 34 CheckSharedIntegerTypedArray(ia); 35 if (!%IsSharedInteger32TypedArray(ia)) { 36 throw MakeTypeError(kNotInt32SharedTypedArray, ia); 37 } 38} 39 40//------------------------------------------------------------------- 41 42function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) { 43 CheckSharedIntegerTypedArray(sta); 44 index = TO_INTEGER(index); 45 if (index < 0 || index >= %_TypedArrayGetLength(sta)) { 46 return UNDEFINED; 47 } 48 oldValue = TO_NUMBER(oldValue); 49 newValue = TO_NUMBER(newValue); 50 return %_AtomicsCompareExchange(sta, index, oldValue, newValue); 51} 52 53function AtomicsLoadJS(sta, index) { 54 CheckSharedIntegerTypedArray(sta); 55 index = TO_INTEGER(index); 56 if (index < 0 || index >= %_TypedArrayGetLength(sta)) { 57 return UNDEFINED; 58 } 59 return %_AtomicsLoad(sta, index); 60} 61 62function AtomicsStoreJS(sta, index, value) { 63 CheckSharedIntegerTypedArray(sta); 64 index = TO_INTEGER(index); 65 if (index < 0 || index >= %_TypedArrayGetLength(sta)) { 66 return UNDEFINED; 67 } 68 value = TO_NUMBER(value); 69 return %_AtomicsStore(sta, index, value); 70} 71 72function AtomicsAddJS(ia, index, value) { 73 CheckSharedIntegerTypedArray(ia); 74 index = TO_INTEGER(index); 75 if (index < 0 || index >= %_TypedArrayGetLength(ia)) { 76 return UNDEFINED; 77 } 78 value = TO_NUMBER(value); 79 return %_AtomicsAdd(ia, index, value); 80} 81 82function AtomicsSubJS(ia, index, value) { 83 CheckSharedIntegerTypedArray(ia); 84 index = TO_INTEGER(index); 85 if (index < 0 || index >= %_TypedArrayGetLength(ia)) { 86 return UNDEFINED; 87 } 88 value = TO_NUMBER(value); 89 return %_AtomicsSub(ia, index, value); 90} 91 92function AtomicsAndJS(ia, index, value) { 93 CheckSharedIntegerTypedArray(ia); 94 index = TO_INTEGER(index); 95 if (index < 0 || index >= %_TypedArrayGetLength(ia)) { 96 return UNDEFINED; 97 } 98 value = TO_NUMBER(value); 99 return %_AtomicsAnd(ia, index, value); 100} 101 102function AtomicsOrJS(ia, index, value) { 103 CheckSharedIntegerTypedArray(ia); 104 index = TO_INTEGER(index); 105 if (index < 0 || index >= %_TypedArrayGetLength(ia)) { 106 return UNDEFINED; 107 } 108 value = TO_NUMBER(value); 109 return %_AtomicsOr(ia, index, value); 110} 111 112function AtomicsXorJS(ia, index, value) { 113 CheckSharedIntegerTypedArray(ia); 114 index = TO_INTEGER(index); 115 if (index < 0 || index >= %_TypedArrayGetLength(ia)) { 116 return UNDEFINED; 117 } 118 value = TO_NUMBER(value); 119 return %_AtomicsXor(ia, index, value); 120} 121 122function AtomicsExchangeJS(ia, index, value) { 123 CheckSharedIntegerTypedArray(ia); 124 index = TO_INTEGER(index); 125 if (index < 0 || index >= %_TypedArrayGetLength(ia)) { 126 return UNDEFINED; 127 } 128 value = TO_NUMBER(value); 129 return %_AtomicsExchange(ia, index, value); 130} 131 132function AtomicsIsLockFreeJS(size) { 133 return %_AtomicsIsLockFree(size); 134} 135 136// Futexes 137 138function AtomicsFutexWaitJS(ia, index, value, timeout) { 139 CheckSharedInteger32TypedArray(ia); 140 index = TO_INTEGER(index); 141 if (index < 0 || index >= %_TypedArrayGetLength(ia)) { 142 return UNDEFINED; 143 } 144 if (IS_UNDEFINED(timeout)) { 145 timeout = INFINITY; 146 } else { 147 timeout = TO_NUMBER(timeout); 148 if (NUMBER_IS_NAN(timeout)) { 149 timeout = INFINITY; 150 } else { 151 timeout = MaxSimple(0, timeout); 152 } 153 } 154 return %AtomicsFutexWait(ia, index, value, timeout); 155} 156 157function AtomicsFutexWakeJS(ia, index, count) { 158 CheckSharedInteger32TypedArray(ia); 159 index = TO_INTEGER(index); 160 if (index < 0 || index >= %_TypedArrayGetLength(ia)) { 161 return UNDEFINED; 162 } 163 count = MaxSimple(0, TO_INTEGER(count)); 164 return %AtomicsFutexWake(ia, index, count); 165} 166 167function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) { 168 CheckSharedInteger32TypedArray(ia); 169 index1 = TO_INTEGER(index1); 170 count = MaxSimple(0, TO_INTEGER(count)); 171 value = TO_INT32(value); 172 index2 = TO_INTEGER(index2); 173 if (index1 < 0 || index1 >= %_TypedArrayGetLength(ia) || 174 index2 < 0 || index2 >= %_TypedArrayGetLength(ia)) { 175 return UNDEFINED; 176 } 177 return %AtomicsFutexWakeOrRequeue(ia, index1, count, value, index2); 178} 179 180// ------------------------------------------------------------------- 181 182function AtomicsConstructor() {} 183 184var Atomics = new AtomicsConstructor(); 185 186%InternalSetPrototype(Atomics, GlobalObject.prototype); 187%AddNamedProperty(global, "Atomics", Atomics, DONT_ENUM); 188%FunctionSetInstanceClassName(AtomicsConstructor, 'Atomics'); 189 190%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM); 191 192// These must match the values in src/futex-emulation.h 193utils.InstallConstants(Atomics, [ 194 "OK", 0, 195 "NOTEQUAL", -1, 196 "TIMEDOUT", -2, 197]); 198 199utils.InstallFunctions(Atomics, DONT_ENUM, [ 200 "compareExchange", AtomicsCompareExchangeJS, 201 "load", AtomicsLoadJS, 202 "store", AtomicsStoreJS, 203 "add", AtomicsAddJS, 204 "sub", AtomicsSubJS, 205 "and", AtomicsAndJS, 206 "or", AtomicsOrJS, 207 "xor", AtomicsXorJS, 208 "exchange", AtomicsExchangeJS, 209 "isLockFree", AtomicsIsLockFreeJS, 210 "futexWait", AtomicsFutexWaitJS, 211 "futexWake", AtomicsFutexWakeJS, 212 "futexWakeOrRequeue", AtomicsFutexWakeOrRequeueJS, 213]); 214 215}) 216