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.
5 (function(global, utils) {
9 %CheckIsBootstrapping();
11 // -------------------------------------------------------------------
14 var GlobalObject = global.Object;
18 utils.Import(function(from) {
19 MathMax = from.MathMax;
22 // -------------------------------------------------------------------
25 function CheckSharedTypedArray(sta) {
26 if (!%IsSharedTypedArray(sta)) {
27 throw MakeTypeError(kNotSharedTypedArray, sta);
31 function CheckSharedIntegerTypedArray(ia) {
32 if (!%IsSharedIntegerTypedArray(ia)) {
33 throw MakeTypeError(kNotIntegerSharedTypedArray, ia);
37 function CheckSharedInteger32TypedArray(ia) {
38 CheckSharedIntegerTypedArray(ia);
39 if (%_ClassOf(ia) !== 'Int32Array') {
40 throw MakeTypeError(kNotInt32SharedTypedArray, ia);
44 //-------------------------------------------------------------------
46 function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) {
47 CheckSharedTypedArray(sta);
48 index = $toInteger(index);
49 if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
52 oldValue = $toNumber(oldValue);
53 newValue = $toNumber(newValue);
54 return %_AtomicsCompareExchange(sta, index, oldValue, newValue);
57 function AtomicsLoadJS(sta, index) {
58 CheckSharedTypedArray(sta);
59 index = $toInteger(index);
60 if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
63 return %_AtomicsLoad(sta, index);
66 function AtomicsStoreJS(sta, index, value) {
67 CheckSharedTypedArray(sta);
68 index = $toInteger(index);
69 if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
72 value = $toNumber(value);
73 return %_AtomicsStore(sta, index, value);
76 function AtomicsAddJS(ia, index, value) {
77 CheckSharedIntegerTypedArray(ia);
78 index = $toInteger(index);
79 if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
82 value = $toNumber(value);
83 return %_AtomicsAdd(ia, index, value);
86 function AtomicsSubJS(ia, index, value) {
87 CheckSharedIntegerTypedArray(ia);
88 index = $toInteger(index);
89 if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
92 value = $toNumber(value);
93 return %_AtomicsSub(ia, index, value);
96 function AtomicsAndJS(ia, index, value) {
97 CheckSharedIntegerTypedArray(ia);
98 index = $toInteger(index);
99 if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
102 value = $toNumber(value);
103 return %_AtomicsAnd(ia, index, value);
106 function AtomicsOrJS(ia, index, value) {
107 CheckSharedIntegerTypedArray(ia);
108 index = $toInteger(index);
109 if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
112 value = $toNumber(value);
113 return %_AtomicsOr(ia, index, value);
116 function AtomicsXorJS(ia, index, value) {
117 CheckSharedIntegerTypedArray(ia);
118 index = $toInteger(index);
119 if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
122 value = $toNumber(value);
123 return %_AtomicsXor(ia, index, value);
126 function AtomicsExchangeJS(ia, index, value) {
127 CheckSharedIntegerTypedArray(ia);
128 index = $toInteger(index);
129 if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
132 value = $toNumber(value);
133 return %_AtomicsExchange(ia, index, value);
136 function AtomicsIsLockFreeJS(size) {
137 return %_AtomicsIsLockFree(size);
142 function AtomicsFutexWaitJS(ia, index, value, timeout) {
143 CheckSharedInteger32TypedArray(ia);
144 index = $toInteger(index);
145 if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
148 if (IS_UNDEFINED(timeout)) {
151 timeout = $toNumber(timeout);
152 if (NUMBER_IS_NAN(timeout)) {
155 timeout = MathMax(0, timeout);
158 return %AtomicsFutexWait(ia, index, value, timeout);
161 function AtomicsFutexWakeJS(ia, index, count) {
162 CheckSharedInteger32TypedArray(ia);
163 index = $toInteger(index);
164 if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
167 count = MathMax(0, $toInteger(count));
168 return %AtomicsFutexWake(ia, index, count);
171 function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) {
172 CheckSharedInteger32TypedArray(ia);
173 index1 = $toInteger(index1);
174 count = MathMax(0, $toInteger(count));
175 value = TO_INT32(value);
176 index2 = $toInteger(index2);
177 if (index1 < 0 || index1 >= %_TypedArrayGetLength(ia) ||
178 index2 < 0 || index2 >= %_TypedArrayGetLength(ia)) {
181 return %AtomicsFutexWakeOrRequeue(ia, index1, count, value, index2);
184 // -------------------------------------------------------------------
186 function AtomicsConstructor() {}
188 var Atomics = new AtomicsConstructor();
190 %InternalSetPrototype(Atomics, GlobalObject.prototype);
191 %AddNamedProperty(global, "Atomics", Atomics, DONT_ENUM);
192 %FunctionSetInstanceClassName(AtomicsConstructor, 'Atomics');
194 %AddNamedProperty(Atomics, symbolToStringTag, "Atomics", READ_ONLY | DONT_ENUM);
196 // These must match the values in src/futex-emulation.h
197 utils.InstallConstants(Atomics, [
203 utils.InstallFunctions(Atomics, DONT_ENUM, [
204 "compareExchange", AtomicsCompareExchangeJS,
205 "load", AtomicsLoadJS,
206 "store", AtomicsStoreJS,
212 "exchange", AtomicsExchangeJS,
213 "isLockFree", AtomicsIsLockFreeJS,
214 "futexWait", AtomicsFutexWaitJS,
215 "futexWake", AtomicsFutexWakeJS,
216 "futexWakeOrRequeue", AtomicsFutexWakeOrRequeueJS,