| // Copyright (C) 2017 Mozilla Corporation. All rights reserved. |
| // This code is governed by the BSD license found in the LICENSE file. |
| /*--- |
| description: | |
| Collection of functions used to assert the correctness of SharedArrayBuffer objects. |
| defines: |
| - testWithAtomicsOutOfBoundsIndices |
| - testWithAtomicsInBoundsIndices |
| - testWithAtomicsNonViewValues |
| ---*/ |
| |
| |
| /** |
| * Calls the provided function for a each bad index that should throw a |
| * RangeError when passed to an Atomics method on a SAB-backed view where |
| * index 125 is out of range. |
| * |
| * @param f - the function to call for each bad index. |
| */ |
| function testWithAtomicsOutOfBoundsIndices(f) { |
| var bad_indices = [ |
| function(view) { return -1; }, |
| function(view) { return view.length; }, |
| function(view) { return view.length * 2; }, |
| function(view) { return Number.POSITIVE_INFINITY; }, |
| function(view) { return Number.NEGATIVE_INFINITY; }, |
| function(view) { return { valueOf: function() { return 125; } }; }, |
| function(view) { return { toString: function() { return '125'; }, valueOf: false }; }, // non-callable valueOf triggers invocation of toString |
| ]; |
| |
| for (var i = 0; i < bad_indices.length; ++i) { |
| var IdxGen = bad_indices[i]; |
| try { |
| f(IdxGen); |
| } catch (e) { |
| e.message += ' (Testing with index gen ' + IdxGen + '.)'; |
| throw e; |
| } |
| } |
| } |
| |
| /** |
| * Calls the provided function for each good index that should not throw when |
| * passed to an Atomics method on a SAB-backed view. |
| * |
| * The view must have length greater than zero. |
| * |
| * @param f - the function to call for each good index. |
| */ |
| function testWithAtomicsInBoundsIndices(f) { |
| // Most of these are eventually coerced to +0 by ToIndex. |
| var good_indices = [ |
| function(view) { return 0/-1; }, |
| function(view) { return '-0'; }, |
| function(view) { return undefined; }, |
| function(view) { return NaN; }, |
| function(view) { return 0.5; }, |
| function(view) { return '0.5'; }, |
| function(view) { return -0.9; }, |
| function(view) { return { password: 'qumquat' }; }, |
| function(view) { return view.length - 1; }, |
| function(view) { return { valueOf: function() { return 0; } }; }, |
| function(view) { return { toString: function() { return '0'; }, valueOf: false }; }, // non-callable valueOf triggers invocation of toString |
| ]; |
| |
| for (var i = 0; i < good_indices.length; ++i) { |
| var IdxGen = good_indices[i]; |
| try { |
| f(IdxGen); |
| } catch (e) { |
| e.message += ' (Testing with index gen ' + IdxGen + '.)'; |
| throw e; |
| } |
| } |
| } |
| |
| /** |
| * Calls the provided function for each value that should throw a TypeError |
| * when passed to an Atomics method as a view. |
| * |
| * @param f - the function to call for each non-view value. |
| */ |
| |
| function testWithAtomicsNonViewValues(f) { |
| var values = [ |
| null, |
| undefined, |
| true, |
| false, |
| new Boolean(true), |
| 10, |
| 3.14, |
| new Number(4), |
| 'Hi there', |
| new Date, |
| /a*utomaton/g, |
| { password: 'qumquat' }, |
| new DataView(new ArrayBuffer(10)), |
| new ArrayBuffer(128), |
| new SharedArrayBuffer(128), |
| new Error('Ouch'), |
| [1,1,2,3,5,8], |
| function(x) { return -x; }, |
| Symbol('halleluja'), |
| // TODO: Proxy? |
| Object, |
| Int32Array, |
| Date, |
| Math, |
| Atomics |
| ]; |
| |
| for (var i = 0; i < values.length; ++i) { |
| var nonView = values[i]; |
| try { |
| f(nonView); |
| } catch (e) { |
| e.message += ' (Testing with non-view value ' + nonView + '.)'; |
| throw e; |
| } |
| } |
| } |
| |