Index: test/mjsunit/harmony/atomics.js |
diff --git a/test/mjsunit/harmony/atomics.js b/test/mjsunit/harmony/atomics.js |
index 202725297abbaef3ce0ef4ac46db29fc2dff0558..ff403b8bd1d47cc0b53d994220abc90025ec52f7 100644 |
--- a/test/mjsunit/harmony/atomics.js |
+++ b/test/mjsunit/harmony/atomics.js |
@@ -5,15 +5,37 @@ |
// Flags: --harmony-atomics --harmony-sharedarraybuffer |
// |
+function toRangeWrapped(value) { |
+ var range = this.max - this.min + 1; |
+ while (value < this.min) { |
+ value += range; |
+ } |
+ while (value > this.max) { |
+ value -= range; |
+ } |
+ return value; |
+} |
+ |
+function toRangeClamped(value) { |
+ if (value < this.min) return this.min; |
+ if (value > this.max) return this.max; |
+ return value; |
+} |
+ |
+function makeConstructorObject(constr, min, max, toRange) { |
+ var o = {constr: constr, min: min, max: max}; |
+ o.toRange = toRange.bind(o); |
+ return o; |
+} |
+ |
var IntegerTypedArrayConstructors = [ |
- {constr: Int8Array, min: -128, max: 127}, |
- {constr: Int16Array, min: -32768, max: 32767}, |
- {constr: Int32Array, min: -0x80000000, max: 0x7fffffff}, |
- {constr: Uint8Array, min: 0, max: 255}, |
-// TODO(binji): support? |
-// {constr: Uint8ClampedArray, min: 0, max: 255}, |
- {constr: Uint16Array, min: 0, max: 65535}, |
- {constr: Uint32Array, min: 0, max: 0xffffffff}, |
+ makeConstructorObject(Int8Array, -128, 127, toRangeWrapped), |
+ makeConstructorObject(Int16Array, -32768, 32767, toRangeWrapped), |
+ makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff, toRangeWrapped), |
+ makeConstructorObject(Uint8Array, 0, 255, toRangeWrapped), |
+ makeConstructorObject(Uint8ClampedArray, 0, 255, toRangeClamped), |
+ makeConstructorObject(Uint16Array, 0, 65535, toRangeWrapped), |
+ makeConstructorObject(Uint32Array, 0, 0xffffffff, toRangeWrapped), |
]; |
var TypedArrayConstructors = IntegerTypedArrayConstructors.concat([ |
@@ -141,33 +163,6 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { |
} |
}); |
- IntegerTypedArrayConstructors.forEach(function(t) { |
- var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
- var sta = new t.constr(sab); |
- var name = Object.prototype.toString.call(sta); |
- var range = t.max - t.min + 1; |
- var add; |
- var oldVal, oldValWrapped; |
- var newVal, newValWrapped; |
- |
- for (add = -range; add <= range; add += range) { |
- sta[0] = oldVal = 0; |
- newVal = t.max + add + 1; |
- newValWrapped = t.min; |
- assertEquals(oldVal, |
- Atomics.compareExchange(sta, 0, oldVal, newVal), name); |
- assertEquals(newValWrapped, sta[0], name); |
- |
- oldVal = newVal; |
- oldValWrapped = newValWrapped; |
- newVal = t.min + add - 1; |
- newValWrapped = t.max; |
- assertEquals(oldValWrapped, |
- Atomics.compareExchange(sta, 0, oldVal, newVal), name); |
- assertEquals(newValWrapped, sta[0], name); |
- } |
- }); |
- |
// * Exact float values should be OK |
// * Infinity, -Infinity should be OK (has exact representation) |
// * NaN is not OK, it has many representations, cannot ensure successful CAS |
@@ -219,28 +214,6 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { |
} |
}); |
- IntegerTypedArrayConstructors.forEach(function(t) { |
- var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
- var sta = new t.constr(sab); |
- var name = Object.prototype.toString.call(sta); |
- var range = t.max - t.min + 1; |
- var add; |
- var val, valWrapped; |
- |
- for (add = -range; add <= range; add += range) { |
- sta[0] = 0; |
- val = t.max + add + 1; |
- valWrapped = t.min; |
- assertEquals(val, Atomics.store(sta, 0, val), name); |
- assertEquals(valWrapped, sta[0], name); |
- |
- val = t.min + add - 1; |
- valWrapped = t.max; |
- assertEquals(val, Atomics.store(sta, 0, val), name); |
- assertEquals(valWrapped, sta[0], name); |
- } |
- }); |
- |
[1.5, 4.25, -1e8, -Infinity, Infinity, NaN].forEach(function(v) { |
var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT); |
var sf32a = new Float32Array(sab); |
@@ -269,24 +242,6 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { |
assertEquals(120, sta[i], name); |
} |
}); |
- |
- IntegerTypedArrayConstructors.forEach(function(t) { |
- var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
- var sta = new t.constr(sab); |
- var name = Object.prototype.toString.call(sta); |
- var range = t.max - t.min + 1; |
- var add; |
- |
- for (add = -range; add <= range; add += range) { |
- sta[0] = t.max; |
- valWrapped = t.min; |
- assertEquals(t.max, Atomics.add(sta, 0, add + 1), name); |
- assertEquals(t.min, sta[0], name); |
- |
- assertEquals(t.min, Atomics.add(sta, 0, add - 1), name); |
- assertEquals(t.max, sta[0], name); |
- } |
- }); |
})(); |
(function TestSub() { |
@@ -303,24 +258,6 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { |
assertEquals(0, sta[i], name); |
} |
}); |
- |
- IntegerTypedArrayConstructors.forEach(function(t) { |
- var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
- var sta = new t.constr(sab); |
- var name = Object.prototype.toString.call(sta); |
- var range = t.max - t.min + 1; |
- var add; |
- |
- for (add = -range; add <= range; add += range) { |
- sta[0] = t.max; |
- valWrapped = t.min; |
- assertEquals(t.max, Atomics.sub(sta, 0, add - 1), name); |
- assertEquals(t.min, sta[0], name); |
- |
- assertEquals(t.min, Atomics.sub(sta, 0, add + 1), name); |
- assertEquals(t.max, sta[0], name); |
- } |
- }); |
})(); |
(function TestAnd() { |
@@ -337,22 +274,6 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { |
assertEquals(0x20, sta[i], name); |
} |
}); |
- |
- IntegerTypedArrayConstructors.forEach(function(t) { |
- var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
- var sta = new t.constr(sab); |
- var name = Object.prototype.toString.call(sta); |
- var range = t.max - t.min + 1; |
- var add; |
- |
- // There's no way to wrap results with logical operators, just test that |
- // using an out-of-range value is properly masked. |
- for (add = -range; add <= range; add += range) { |
- sta[0] = 0xf; |
- assertEquals(0xf, Atomics.and(sta, 0, 0x3 + add), name); |
- assertEquals(0x3, sta[0], name); |
- } |
- }); |
})(); |
(function TestOr() { |
@@ -369,22 +290,6 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { |
assertEquals(0x3d, sta[i], name); |
} |
}); |
- |
- IntegerTypedArrayConstructors.forEach(function(t) { |
- var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
- var sta = new t.constr(sab); |
- var name = Object.prototype.toString.call(sta); |
- var range = t.max - t.min + 1; |
- var add; |
- |
- // There's no way to wrap results with logical operators, just test that |
- // using an out-of-range value is properly masked. |
- for (add = -range; add <= range; add += range) { |
- sta[0] = 0x12; |
- assertEquals(0x12, Atomics.or(sta, 0, 0x22 + add), name); |
- assertEquals(0x32, sta[0], name); |
- } |
- }); |
})(); |
(function TestXor() { |
@@ -401,22 +306,6 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { |
assertEquals(0x25, sta[i], name); |
} |
}); |
- |
- IntegerTypedArrayConstructors.forEach(function(t) { |
- var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
- var sta = new t.constr(sab); |
- var name = Object.prototype.toString.call(sta); |
- var range = t.max - t.min + 1; |
- var add; |
- |
- // There's no way to wrap results with logical operators, just test that |
- // using an out-of-range value is properly masked. |
- for (add = -range; add <= range; add += range) { |
- sta[0] = 0x12; |
- assertEquals(0x12, Atomics.xor(sta, 0, 0x22 + add), name); |
- assertEquals(0x30, sta[0], name); |
- } |
- }); |
})(); |
(function TestExchange() { |
@@ -433,22 +322,6 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { |
assertEquals(0x09, sta[i], name); |
} |
}); |
- |
- IntegerTypedArrayConstructors.forEach(function(t) { |
- var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
- var sta = new t.constr(sab); |
- var name = Object.prototype.toString.call(sta); |
- var range = t.max - t.min + 1; |
- var add; |
- |
- // There's no way to wrap results with logical operators, just test that |
- // using an out-of-range value is properly masked. |
- for (add = -range; add <= range; add += range) { |
- sta[0] = 0x12; |
- assertEquals(0x12, Atomics.exchange(sta, 0, 0x22 + add), name); |
- assertEquals(0x22, sta[0], name); |
- } |
- }); |
})(); |
(function TestIsLockFree() { |
@@ -470,3 +343,102 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { |
} |
} |
})(); |
+ |
+(function TestWrapping() { |
+ IntegerTypedArrayConstructors.forEach(function(t) { |
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
+ var sta = new t.constr(sab); |
+ var name = Object.prototype.toString.call(sta); |
+ var range = t.max - t.min + 1; |
+ var offset; |
+ var operand; |
+ var val, newVal; |
+ var valWrapped, newValWrapped; |
+ |
+ for (offset = -range; offset <= range; offset += range) { |
+ // CompareExchange |
+ sta[0] = val = 0; |
+ newVal = val + offset + 1; |
+ newValWrapped = t.toRange(newVal); |
+ assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name); |
+ assertEquals(newValWrapped, sta[0], name); |
+ |
+ sta[0] = val = t.min; |
+ newVal = val + offset - 1; |
+ newValWrapped = t.toRange(newVal); |
+ assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name); |
+ assertEquals(newValWrapped, sta[0], name); |
+ |
+ // Store |
+ sta[0] = 0; |
+ val = t.max + offset + 1; |
+ valWrapped = t.toRange(val); |
+ assertEquals(val, Atomics.store(sta, 0, val), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ |
+ sta[0] = val = t.min + offset - 1; |
+ valWrapped = t.toRange(val); |
+ assertEquals(val, Atomics.store(sta, 0, val), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ |
+ // Add |
+ sta[0] = val = t.max; |
+ operand = offset + 1; |
+ valWrapped = t.toRange(val + operand); |
+ assertEquals(val, Atomics.add(sta, 0, operand), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ |
+ sta[0] = val = t.min; |
+ operand = offset - 1; |
+ valWrapped = t.toRange(val + operand); |
+ assertEquals(val, Atomics.add(sta, 0, operand), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ |
+ // Sub |
+ sta[0] = val = t.max; |
+ operand = offset - 1; |
+ valWrapped = t.toRange(val - operand); |
+ assertEquals(val, Atomics.sub(sta, 0, operand), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ |
+ sta[0] = val = t.min; |
+ operand = offset + 1; |
+ valWrapped = t.toRange(val - operand); |
+ assertEquals(val, Atomics.sub(sta, 0, operand), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ |
+ // There's no way to wrap results with logical operators, just test that |
+ // using an out-of-range value is properly wrapped/clamped when written |
+ // to memory. |
+ |
+ // And |
+ sta[0] = val = 0xf; |
+ operand = 0x3 + offset; |
+ valWrapped = t.toRange(val & operand); |
+ assertEquals(val, Atomics.and(sta, 0, operand), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ |
+ // Or |
+ sta[0] = val = 0x12; |
+ operand = 0x22 + offset; |
+ valWrapped = t.toRange(val | operand); |
+ assertEquals(val, Atomics.or(sta, 0, operand), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ |
+ // Xor |
+ sta[0] = val = 0x12; |
+ operand = 0x22 + offset; |
+ valWrapped = t.toRange(val ^ operand); |
+ assertEquals(val, Atomics.xor(sta, 0, operand), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ |
+ // Exchange |
+ sta[0] = val = 0x12; |
+ operand = 0x22 + offset; |
+ valWrapped = t.toRange(operand); |
+ assertEquals(val, Atomics.exchange(sta, 0, operand), name); |
+ assertEquals(valWrapped, sta[0], name); |
+ } |
+ |
+ }); |
+})(); |