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