OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Flags: --harmony-atomics --harmony-sharedarraybuffer | 5 // Flags: --harmony-atomics --harmony-sharedarraybuffer |
6 // | 6 // |
7 | 7 |
| 8 function toRangeWrapped(value) { |
| 9 var range = this.max - this.min + 1; |
| 10 while (value < this.min) { |
| 11 value += range; |
| 12 } |
| 13 while (value > this.max) { |
| 14 value -= range; |
| 15 } |
| 16 return value; |
| 17 } |
| 18 |
| 19 function toRangeClamped(value) { |
| 20 if (value < this.min) return this.min; |
| 21 if (value > this.max) return this.max; |
| 22 return value; |
| 23 } |
| 24 |
| 25 function makeConstructorObject(constr, min, max, toRange) { |
| 26 var o = {constr: constr, min: min, max: max}; |
| 27 o.toRange = toRange.bind(o); |
| 28 return o; |
| 29 } |
| 30 |
8 var IntegerTypedArrayConstructors = [ | 31 var IntegerTypedArrayConstructors = [ |
9 {constr: Int8Array, min: -128, max: 127}, | 32 makeConstructorObject(Int8Array, -128, 127, toRangeWrapped), |
10 {constr: Int16Array, min: -32768, max: 32767}, | 33 makeConstructorObject(Int16Array, -32768, 32767, toRangeWrapped), |
11 {constr: Int32Array, min: -0x80000000, max: 0x7fffffff}, | 34 makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff, toRangeWrapped), |
12 {constr: Uint8Array, min: 0, max: 255}, | 35 makeConstructorObject(Uint8Array, 0, 255, toRangeWrapped), |
13 // TODO(binji): support? | 36 makeConstructorObject(Uint8ClampedArray, 0, 255, toRangeClamped), |
14 // {constr: Uint8ClampedArray, min: 0, max: 255}, | 37 makeConstructorObject(Uint16Array, 0, 65535, toRangeWrapped), |
15 {constr: Uint16Array, min: 0, max: 65535}, | 38 makeConstructorObject(Uint32Array, 0, 0xffffffff, toRangeWrapped), |
16 {constr: Uint32Array, min: 0, max: 0xffffffff}, | |
17 ]; | 39 ]; |
18 | 40 |
19 var TypedArrayConstructors = IntegerTypedArrayConstructors.concat([ | 41 var TypedArrayConstructors = IntegerTypedArrayConstructors.concat([ |
20 {constr: Float32Array}, | 42 {constr: Float32Array}, |
21 {constr: Float64Array}, | 43 {constr: Float64Array}, |
22 ]); | 44 ]); |
23 | 45 |
24 (function TestBadArray() { | 46 (function TestBadArray() { |
25 var ab = new ArrayBuffer(16); | 47 var ab = new ArrayBuffer(16); |
26 var u32a = new Uint32Array(16); | 48 var u32a = new Uint32Array(16); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 // sta[i] == 0, CAS will store | 156 // sta[i] == 0, CAS will store |
135 assertEquals(0, Atomics.compareExchange(sta, i, 0, 50), name); | 157 assertEquals(0, Atomics.compareExchange(sta, i, 0, 50), name); |
136 assertEquals(50, sta[i], name); | 158 assertEquals(50, sta[i], name); |
137 | 159 |
138 // sta[i] == 50, CAS will not store | 160 // sta[i] == 50, CAS will not store |
139 assertEquals(50, Atomics.compareExchange(sta, i, 0, 100), name); | 161 assertEquals(50, Atomics.compareExchange(sta, i, 0, 100), name); |
140 assertEquals(50, sta[i], name); | 162 assertEquals(50, sta[i], name); |
141 } | 163 } |
142 }); | 164 }); |
143 | 165 |
144 IntegerTypedArrayConstructors.forEach(function(t) { | |
145 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | |
146 var sta = new t.constr(sab); | |
147 var name = Object.prototype.toString.call(sta); | |
148 var range = t.max - t.min + 1; | |
149 var add; | |
150 var oldVal, oldValWrapped; | |
151 var newVal, newValWrapped; | |
152 | |
153 for (add = -range; add <= range; add += range) { | |
154 sta[0] = oldVal = 0; | |
155 newVal = t.max + add + 1; | |
156 newValWrapped = t.min; | |
157 assertEquals(oldVal, | |
158 Atomics.compareExchange(sta, 0, oldVal, newVal), name); | |
159 assertEquals(newValWrapped, sta[0], name); | |
160 | |
161 oldVal = newVal; | |
162 oldValWrapped = newValWrapped; | |
163 newVal = t.min + add - 1; | |
164 newValWrapped = t.max; | |
165 assertEquals(oldValWrapped, | |
166 Atomics.compareExchange(sta, 0, oldVal, newVal), name); | |
167 assertEquals(newValWrapped, sta[0], name); | |
168 } | |
169 }); | |
170 | |
171 // * Exact float values should be OK | 166 // * Exact float values should be OK |
172 // * Infinity, -Infinity should be OK (has exact representation) | 167 // * Infinity, -Infinity should be OK (has exact representation) |
173 // * NaN is not OK, it has many representations, cannot ensure successful CAS | 168 // * NaN is not OK, it has many representations, cannot ensure successful CAS |
174 // because it does a bitwise compare | 169 // because it does a bitwise compare |
175 [1.5, 4.25, -1e8, -Infinity, Infinity].forEach(function(v) { | 170 [1.5, 4.25, -1e8, -Infinity, Infinity].forEach(function(v) { |
176 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT); | 171 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT); |
177 var sf32a = new Float32Array(sab); | 172 var sf32a = new Float32Array(sab); |
178 sf32a[0] = 0; | 173 sf32a[0] = 0; |
179 assertEquals(0, Atomics.compareExchange(sf32a, 0, 0, v)); | 174 assertEquals(0, Atomics.compareExchange(sf32a, 0, 0, v)); |
180 assertEquals(v, sf32a[0]); | 175 assertEquals(v, sf32a[0]); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 var name = Object.prototype.toString.call(sta); | 207 var name = Object.prototype.toString.call(sta); |
213 for (var i = 0; i < 10; ++i) { | 208 for (var i = 0; i < 10; ++i) { |
214 assertEquals(50, Atomics.store(sta, i, 50), name); | 209 assertEquals(50, Atomics.store(sta, i, 50), name); |
215 assertEquals(50, sta[i], name); | 210 assertEquals(50, sta[i], name); |
216 | 211 |
217 assertEquals(100, Atomics.store(sta, i, 100), name); | 212 assertEquals(100, Atomics.store(sta, i, 100), name); |
218 assertEquals(100, sta[i], name); | 213 assertEquals(100, sta[i], name); |
219 } | 214 } |
220 }); | 215 }); |
221 | 216 |
222 IntegerTypedArrayConstructors.forEach(function(t) { | |
223 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | |
224 var sta = new t.constr(sab); | |
225 var name = Object.prototype.toString.call(sta); | |
226 var range = t.max - t.min + 1; | |
227 var add; | |
228 var val, valWrapped; | |
229 | |
230 for (add = -range; add <= range; add += range) { | |
231 sta[0] = 0; | |
232 val = t.max + add + 1; | |
233 valWrapped = t.min; | |
234 assertEquals(val, Atomics.store(sta, 0, val), name); | |
235 assertEquals(valWrapped, sta[0], name); | |
236 | |
237 val = t.min + add - 1; | |
238 valWrapped = t.max; | |
239 assertEquals(val, Atomics.store(sta, 0, val), name); | |
240 assertEquals(valWrapped, sta[0], name); | |
241 } | |
242 }); | |
243 | |
244 [1.5, 4.25, -1e8, -Infinity, Infinity, NaN].forEach(function(v) { | 217 [1.5, 4.25, -1e8, -Infinity, Infinity, NaN].forEach(function(v) { |
245 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT); | 218 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT); |
246 var sf32a = new Float32Array(sab); | 219 var sf32a = new Float32Array(sab); |
247 sf32a[0] = 0; | 220 sf32a[0] = 0; |
248 assertEquals(v, Atomics.store(sf32a, 0, v)); | 221 assertEquals(v, Atomics.store(sf32a, 0, v)); |
249 assertEquals(v, sf32a[0]); | 222 assertEquals(v, sf32a[0]); |
250 | 223 |
251 var sab2 = new SharedArrayBuffer(10 * Float64Array.BYTES_PER_ELEMENT); | 224 var sab2 = new SharedArrayBuffer(10 * Float64Array.BYTES_PER_ELEMENT); |
252 var sf64a = new Float64Array(sab2); | 225 var sf64a = new Float64Array(sab2); |
253 sf64a[0] = 0; | 226 sf64a[0] = 0; |
254 assertEquals(v, Atomics.store(sf64a, 0, v)); | 227 assertEquals(v, Atomics.store(sf64a, 0, v)); |
255 assertEquals(v, sf64a[0]); | 228 assertEquals(v, sf64a[0]); |
256 }); | 229 }); |
257 })(); | 230 })(); |
258 | 231 |
259 (function TestAdd() { | 232 (function TestAdd() { |
260 IntegerTypedArrayConstructors.forEach(function(t) { | 233 IntegerTypedArrayConstructors.forEach(function(t) { |
261 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 234 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
262 var sta = new t.constr(sab); | 235 var sta = new t.constr(sab); |
263 var name = Object.prototype.toString.call(sta); | 236 var name = Object.prototype.toString.call(sta); |
264 for (var i = 0; i < 10; ++i) { | 237 for (var i = 0; i < 10; ++i) { |
265 assertEquals(0, Atomics.add(sta, i, 50), name); | 238 assertEquals(0, Atomics.add(sta, i, 50), name); |
266 assertEquals(50, sta[i], name); | 239 assertEquals(50, sta[i], name); |
267 | 240 |
268 assertEquals(50, Atomics.add(sta, i, 70), name); | 241 assertEquals(50, Atomics.add(sta, i, 70), name); |
269 assertEquals(120, sta[i], name); | 242 assertEquals(120, sta[i], name); |
270 } | 243 } |
271 }); | 244 }); |
272 | |
273 IntegerTypedArrayConstructors.forEach(function(t) { | |
274 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | |
275 var sta = new t.constr(sab); | |
276 var name = Object.prototype.toString.call(sta); | |
277 var range = t.max - t.min + 1; | |
278 var add; | |
279 | |
280 for (add = -range; add <= range; add += range) { | |
281 sta[0] = t.max; | |
282 valWrapped = t.min; | |
283 assertEquals(t.max, Atomics.add(sta, 0, add + 1), name); | |
284 assertEquals(t.min, sta[0], name); | |
285 | |
286 assertEquals(t.min, Atomics.add(sta, 0, add - 1), name); | |
287 assertEquals(t.max, sta[0], name); | |
288 } | |
289 }); | |
290 })(); | 245 })(); |
291 | 246 |
292 (function TestSub() { | 247 (function TestSub() { |
293 IntegerTypedArrayConstructors.forEach(function(t) { | 248 IntegerTypedArrayConstructors.forEach(function(t) { |
294 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 249 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
295 var sta = new t.constr(sab); | 250 var sta = new t.constr(sab); |
296 var name = Object.prototype.toString.call(sta); | 251 var name = Object.prototype.toString.call(sta); |
297 for (var i = 0; i < 10; ++i) { | 252 for (var i = 0; i < 10; ++i) { |
298 sta[i] = 120; | 253 sta[i] = 120; |
299 assertEquals(120, Atomics.sub(sta, i, 50), name); | 254 assertEquals(120, Atomics.sub(sta, i, 50), name); |
300 assertEquals(70, sta[i], name); | 255 assertEquals(70, sta[i], name); |
301 | 256 |
302 assertEquals(70, Atomics.sub(sta, i, 70), name); | 257 assertEquals(70, Atomics.sub(sta, i, 70), name); |
303 assertEquals(0, sta[i], name); | 258 assertEquals(0, sta[i], name); |
304 } | 259 } |
305 }); | 260 }); |
306 | |
307 IntegerTypedArrayConstructors.forEach(function(t) { | |
308 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | |
309 var sta = new t.constr(sab); | |
310 var name = Object.prototype.toString.call(sta); | |
311 var range = t.max - t.min + 1; | |
312 var add; | |
313 | |
314 for (add = -range; add <= range; add += range) { | |
315 sta[0] = t.max; | |
316 valWrapped = t.min; | |
317 assertEquals(t.max, Atomics.sub(sta, 0, add - 1), name); | |
318 assertEquals(t.min, sta[0], name); | |
319 | |
320 assertEquals(t.min, Atomics.sub(sta, 0, add + 1), name); | |
321 assertEquals(t.max, sta[0], name); | |
322 } | |
323 }); | |
324 })(); | 261 })(); |
325 | 262 |
326 (function TestAnd() { | 263 (function TestAnd() { |
327 IntegerTypedArrayConstructors.forEach(function(t) { | 264 IntegerTypedArrayConstructors.forEach(function(t) { |
328 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 265 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
329 var sta = new t.constr(sab); | 266 var sta = new t.constr(sab); |
330 var name = Object.prototype.toString.call(sta); | 267 var name = Object.prototype.toString.call(sta); |
331 for (var i = 0; i < 10; ++i) { | 268 for (var i = 0; i < 10; ++i) { |
332 sta[i] = 0x3f; | 269 sta[i] = 0x3f; |
333 assertEquals(0x3f, Atomics.and(sta, i, 0x30), name); | 270 assertEquals(0x3f, Atomics.and(sta, i, 0x30), name); |
334 assertEquals(0x30, sta[i], name); | 271 assertEquals(0x30, sta[i], name); |
335 | 272 |
336 assertEquals(0x30, Atomics.and(sta, i, 0x20), name); | 273 assertEquals(0x30, Atomics.and(sta, i, 0x20), name); |
337 assertEquals(0x20, sta[i], name); | 274 assertEquals(0x20, sta[i], name); |
338 } | 275 } |
339 }); | 276 }); |
340 | |
341 IntegerTypedArrayConstructors.forEach(function(t) { | |
342 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | |
343 var sta = new t.constr(sab); | |
344 var name = Object.prototype.toString.call(sta); | |
345 var range = t.max - t.min + 1; | |
346 var add; | |
347 | |
348 // There's no way to wrap results with logical operators, just test that | |
349 // using an out-of-range value is properly masked. | |
350 for (add = -range; add <= range; add += range) { | |
351 sta[0] = 0xf; | |
352 assertEquals(0xf, Atomics.and(sta, 0, 0x3 + add), name); | |
353 assertEquals(0x3, sta[0], name); | |
354 } | |
355 }); | |
356 })(); | 277 })(); |
357 | 278 |
358 (function TestOr() { | 279 (function TestOr() { |
359 IntegerTypedArrayConstructors.forEach(function(t) { | 280 IntegerTypedArrayConstructors.forEach(function(t) { |
360 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 281 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
361 var sta = new t.constr(sab); | 282 var sta = new t.constr(sab); |
362 var name = Object.prototype.toString.call(sta); | 283 var name = Object.prototype.toString.call(sta); |
363 for (var i = 0; i < 10; ++i) { | 284 for (var i = 0; i < 10; ++i) { |
364 sta[i] = 0x30; | 285 sta[i] = 0x30; |
365 assertEquals(0x30, Atomics.or(sta, i, 0x1c), name); | 286 assertEquals(0x30, Atomics.or(sta, i, 0x1c), name); |
366 assertEquals(0x3c, sta[i], name); | 287 assertEquals(0x3c, sta[i], name); |
367 | 288 |
368 assertEquals(0x3c, Atomics.or(sta, i, 0x09), name); | 289 assertEquals(0x3c, Atomics.or(sta, i, 0x09), name); |
369 assertEquals(0x3d, sta[i], name); | 290 assertEquals(0x3d, sta[i], name); |
370 } | 291 } |
371 }); | 292 }); |
372 | |
373 IntegerTypedArrayConstructors.forEach(function(t) { | |
374 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | |
375 var sta = new t.constr(sab); | |
376 var name = Object.prototype.toString.call(sta); | |
377 var range = t.max - t.min + 1; | |
378 var add; | |
379 | |
380 // There's no way to wrap results with logical operators, just test that | |
381 // using an out-of-range value is properly masked. | |
382 for (add = -range; add <= range; add += range) { | |
383 sta[0] = 0x12; | |
384 assertEquals(0x12, Atomics.or(sta, 0, 0x22 + add), name); | |
385 assertEquals(0x32, sta[0], name); | |
386 } | |
387 }); | |
388 })(); | 293 })(); |
389 | 294 |
390 (function TestXor() { | 295 (function TestXor() { |
391 IntegerTypedArrayConstructors.forEach(function(t) { | 296 IntegerTypedArrayConstructors.forEach(function(t) { |
392 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 297 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
393 var sta = new t.constr(sab); | 298 var sta = new t.constr(sab); |
394 var name = Object.prototype.toString.call(sta); | 299 var name = Object.prototype.toString.call(sta); |
395 for (var i = 0; i < 10; ++i) { | 300 for (var i = 0; i < 10; ++i) { |
396 sta[i] = 0x30; | 301 sta[i] = 0x30; |
397 assertEquals(0x30, Atomics.xor(sta, i, 0x1c), name); | 302 assertEquals(0x30, Atomics.xor(sta, i, 0x1c), name); |
398 assertEquals(0x2c, sta[i], name); | 303 assertEquals(0x2c, sta[i], name); |
399 | 304 |
400 assertEquals(0x2c, Atomics.xor(sta, i, 0x09), name); | 305 assertEquals(0x2c, Atomics.xor(sta, i, 0x09), name); |
401 assertEquals(0x25, sta[i], name); | 306 assertEquals(0x25, sta[i], name); |
402 } | 307 } |
403 }); | 308 }); |
404 | |
405 IntegerTypedArrayConstructors.forEach(function(t) { | |
406 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | |
407 var sta = new t.constr(sab); | |
408 var name = Object.prototype.toString.call(sta); | |
409 var range = t.max - t.min + 1; | |
410 var add; | |
411 | |
412 // There's no way to wrap results with logical operators, just test that | |
413 // using an out-of-range value is properly masked. | |
414 for (add = -range; add <= range; add += range) { | |
415 sta[0] = 0x12; | |
416 assertEquals(0x12, Atomics.xor(sta, 0, 0x22 + add), name); | |
417 assertEquals(0x30, sta[0], name); | |
418 } | |
419 }); | |
420 })(); | 309 })(); |
421 | 310 |
422 (function TestExchange() { | 311 (function TestExchange() { |
423 IntegerTypedArrayConstructors.forEach(function(t) { | 312 IntegerTypedArrayConstructors.forEach(function(t) { |
424 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 313 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
425 var sta = new t.constr(sab); | 314 var sta = new t.constr(sab); |
426 var name = Object.prototype.toString.call(sta); | 315 var name = Object.prototype.toString.call(sta); |
427 for (var i = 0; i < 10; ++i) { | 316 for (var i = 0; i < 10; ++i) { |
428 sta[i] = 0x30; | 317 sta[i] = 0x30; |
429 assertEquals(0x30, Atomics.exchange(sta, i, 0x1c), name); | 318 assertEquals(0x30, Atomics.exchange(sta, i, 0x1c), name); |
430 assertEquals(0x1c, sta[i], name); | 319 assertEquals(0x1c, sta[i], name); |
431 | 320 |
432 assertEquals(0x1c, Atomics.exchange(sta, i, 0x09), name); | 321 assertEquals(0x1c, Atomics.exchange(sta, i, 0x09), name); |
433 assertEquals(0x09, sta[i], name); | 322 assertEquals(0x09, sta[i], name); |
434 } | 323 } |
435 }); | 324 }); |
436 | |
437 IntegerTypedArrayConstructors.forEach(function(t) { | |
438 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | |
439 var sta = new t.constr(sab); | |
440 var name = Object.prototype.toString.call(sta); | |
441 var range = t.max - t.min + 1; | |
442 var add; | |
443 | |
444 // There's no way to wrap results with logical operators, just test that | |
445 // using an out-of-range value is properly masked. | |
446 for (add = -range; add <= range; add += range) { | |
447 sta[0] = 0x12; | |
448 assertEquals(0x12, Atomics.exchange(sta, 0, 0x22 + add), name); | |
449 assertEquals(0x22, sta[0], name); | |
450 } | |
451 }); | |
452 })(); | 325 })(); |
453 | 326 |
454 (function TestIsLockFree() { | 327 (function TestIsLockFree() { |
455 // For all platforms we support, 1, 2 and 4 bytes should be lock-free. | 328 // For all platforms we support, 1, 2 and 4 bytes should be lock-free. |
456 assertEquals(true, Atomics.isLockFree(1)); | 329 assertEquals(true, Atomics.isLockFree(1)); |
457 assertEquals(true, Atomics.isLockFree(2)); | 330 assertEquals(true, Atomics.isLockFree(2)); |
458 assertEquals(true, Atomics.isLockFree(4)); | 331 assertEquals(true, Atomics.isLockFree(4)); |
459 | 332 |
460 // Sizes that aren't equal to a typedarray BYTES_PER_ELEMENT always return | 333 // Sizes that aren't equal to a typedarray BYTES_PER_ELEMENT always return |
461 // false. | 334 // false. |
462 var validSizes = {}; | 335 var validSizes = {}; |
463 TypedArrayConstructors.forEach(function(t) { | 336 TypedArrayConstructors.forEach(function(t) { |
464 validSizes[t.constr.BYTES_PER_ELEMENT] = true; | 337 validSizes[t.constr.BYTES_PER_ELEMENT] = true; |
465 }); | 338 }); |
466 | 339 |
467 for (var i = 0; i < 1000; ++i) { | 340 for (var i = 0; i < 1000; ++i) { |
468 if (!validSizes[i]) { | 341 if (!validSizes[i]) { |
469 assertEquals(false, Atomics.isLockFree(i)); | 342 assertEquals(false, Atomics.isLockFree(i)); |
470 } | 343 } |
471 } | 344 } |
472 })(); | 345 })(); |
| 346 |
| 347 (function TestWrapping() { |
| 348 IntegerTypedArrayConstructors.forEach(function(t) { |
| 349 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
| 350 var sta = new t.constr(sab); |
| 351 var name = Object.prototype.toString.call(sta); |
| 352 var range = t.max - t.min + 1; |
| 353 var offset; |
| 354 var operand; |
| 355 var val, newVal; |
| 356 var valWrapped, newValWrapped; |
| 357 |
| 358 for (offset = -range; offset <= range; offset += range) { |
| 359 // CompareExchange |
| 360 sta[0] = val = 0; |
| 361 newVal = val + offset + 1; |
| 362 newValWrapped = t.toRange(newVal); |
| 363 assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name); |
| 364 assertEquals(newValWrapped, sta[0], name); |
| 365 |
| 366 sta[0] = val = t.min; |
| 367 newVal = val + offset - 1; |
| 368 newValWrapped = t.toRange(newVal); |
| 369 assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name); |
| 370 assertEquals(newValWrapped, sta[0], name); |
| 371 |
| 372 // Store |
| 373 sta[0] = 0; |
| 374 val = t.max + offset + 1; |
| 375 valWrapped = t.toRange(val); |
| 376 assertEquals(val, Atomics.store(sta, 0, val), name); |
| 377 assertEquals(valWrapped, sta[0], name); |
| 378 |
| 379 sta[0] = val = t.min + offset - 1; |
| 380 valWrapped = t.toRange(val); |
| 381 assertEquals(val, Atomics.store(sta, 0, val), name); |
| 382 assertEquals(valWrapped, sta[0], name); |
| 383 |
| 384 // Add |
| 385 sta[0] = val = t.max; |
| 386 operand = offset + 1; |
| 387 valWrapped = t.toRange(val + operand); |
| 388 assertEquals(val, Atomics.add(sta, 0, operand), name); |
| 389 assertEquals(valWrapped, sta[0], name); |
| 390 |
| 391 sta[0] = val = t.min; |
| 392 operand = offset - 1; |
| 393 valWrapped = t.toRange(val + operand); |
| 394 assertEquals(val, Atomics.add(sta, 0, operand), name); |
| 395 assertEquals(valWrapped, sta[0], name); |
| 396 |
| 397 // Sub |
| 398 sta[0] = val = t.max; |
| 399 operand = offset - 1; |
| 400 valWrapped = t.toRange(val - operand); |
| 401 assertEquals(val, Atomics.sub(sta, 0, operand), name); |
| 402 assertEquals(valWrapped, sta[0], name); |
| 403 |
| 404 sta[0] = val = t.min; |
| 405 operand = offset + 1; |
| 406 valWrapped = t.toRange(val - operand); |
| 407 assertEquals(val, Atomics.sub(sta, 0, operand), name); |
| 408 assertEquals(valWrapped, sta[0], name); |
| 409 |
| 410 // There's no way to wrap results with logical operators, just test that |
| 411 // using an out-of-range value is properly wrapped/clamped when written |
| 412 // to memory. |
| 413 |
| 414 // And |
| 415 sta[0] = val = 0xf; |
| 416 operand = 0x3 + offset; |
| 417 valWrapped = t.toRange(val & operand); |
| 418 assertEquals(val, Atomics.and(sta, 0, operand), name); |
| 419 assertEquals(valWrapped, sta[0], name); |
| 420 |
| 421 // Or |
| 422 sta[0] = val = 0x12; |
| 423 operand = 0x22 + offset; |
| 424 valWrapped = t.toRange(val | operand); |
| 425 assertEquals(val, Atomics.or(sta, 0, operand), name); |
| 426 assertEquals(valWrapped, sta[0], name); |
| 427 |
| 428 // Xor |
| 429 sta[0] = val = 0x12; |
| 430 operand = 0x22 + offset; |
| 431 valWrapped = t.toRange(val ^ operand); |
| 432 assertEquals(val, Atomics.xor(sta, 0, operand), name); |
| 433 assertEquals(valWrapped, sta[0], name); |
| 434 |
| 435 // Exchange |
| 436 sta[0] = val = 0x12; |
| 437 operand = 0x22 + offset; |
| 438 valWrapped = t.toRange(operand); |
| 439 assertEquals(val, Atomics.exchange(sta, 0, operand), name); |
| 440 assertEquals(valWrapped, sta[0], name); |
| 441 } |
| 442 |
| 443 }); |
| 444 })(); |
OLD | NEW |