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