| 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-sharedarraybuffer | 5 // Flags: --harmony-sharedarraybuffer |
| 6 // | 6 // |
| 7 | 7 |
| 8 function toRangeWrapped(value) { | 8 function toRangeWrapped(value) { |
| 9 var range = this.max - this.min + 1; | 9 var range = this.max - this.min + 1; |
| 10 while (value < this.min) { | 10 while (value < this.min) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 assertThrows(function() { Atomics.store(o, 0, 0); }, TypeError); | 53 assertThrows(function() { Atomics.store(o, 0, 0); }, TypeError); |
| 54 assertThrows(function() { Atomics.add(o, 0, 0); }, TypeError); | 54 assertThrows(function() { Atomics.add(o, 0, 0); }, TypeError); |
| 55 assertThrows(function() { Atomics.sub(o, 0, 0); }, TypeError); | 55 assertThrows(function() { Atomics.sub(o, 0, 0); }, TypeError); |
| 56 assertThrows(function() { Atomics.and(o, 0, 0); }, TypeError); | 56 assertThrows(function() { Atomics.and(o, 0, 0); }, TypeError); |
| 57 assertThrows(function() { Atomics.or(o, 0, 0); }, TypeError); | 57 assertThrows(function() { Atomics.or(o, 0, 0); }, TypeError); |
| 58 assertThrows(function() { Atomics.xor(o, 0, 0); }, TypeError); | 58 assertThrows(function() { Atomics.xor(o, 0, 0); }, TypeError); |
| 59 assertThrows(function() { Atomics.exchange(o, 0, 0); }, TypeError); | 59 assertThrows(function() { Atomics.exchange(o, 0, 0); }, TypeError); |
| 60 }); | 60 }); |
| 61 })(); | 61 })(); |
| 62 | 62 |
| 63 function testAtomicOp(op, ia, index, expectedIndex, name) { | |
| 64 for (var i = 0; i < ia.length; ++i) | |
| 65 ia[i] = 22; | |
| 66 | |
| 67 ia[expectedIndex] = 0; | |
| 68 assertEquals(0, op(ia, index, 0, 0), name); | |
| 69 assertEquals(0, ia[expectedIndex], name); | |
| 70 | |
| 71 for (var i = 0; i < ia.length; ++i) { | |
| 72 if (i == expectedIndex) continue; | |
| 73 assertEquals(22, ia[i], name); | |
| 74 } | |
| 75 } | |
| 76 | |
| 77 (function TestBadIndex() { | 63 (function TestBadIndex() { |
| 78 var sab = new SharedArrayBuffer(8); | 64 var sab = new SharedArrayBuffer(8); |
| 79 var si32a = new Int32Array(sab); | 65 var si32a = new Int32Array(sab); |
| 80 var si32a2 = new Int32Array(sab, 4); | 66 var si32a2 = new Int32Array(sab, 4); |
| 81 | 67 |
| 82 // Non-integer indexes are converted to an integer first, so they should all | 68 // Non-integer indexes should throw RangeError. |
| 83 // operate on index 0. | 69 var nonInteger = [1.4, '1.4', NaN, -Infinity, Infinity, undefined, 'hi', {}]; |
| 84 [undefined, null, false, 'hi', {}].forEach(function(i) { | 70 nonInteger.forEach(function(i) { |
| 71 assertThrows(function() { Atomics.compareExchange(si32a, i, 0); }, |
| 72 RangeError); |
| 73 assertThrows(function() { Atomics.load(si32a, i, 0); }, RangeError); |
| 74 assertThrows(function() { Atomics.store(si32a, i, 0); }, RangeError); |
| 75 assertThrows(function() { Atomics.add(si32a, i, 0); }, RangeError); |
| 76 assertThrows(function() { Atomics.sub(si32a, i, 0); }, RangeError); |
| 77 assertThrows(function() { Atomics.and(si32a, i, 0); }, RangeError); |
| 78 assertThrows(function() { Atomics.or(si32a, i, 0); }, RangeError); |
| 79 assertThrows(function() { Atomics.xor(si32a, i, 0); }, RangeError); |
| 80 assertThrows(function() { Atomics.exchange(si32a, i, 0); }, RangeError); |
| 81 }, RangeError); |
| 85 | 82 |
| 86 var name = String(i); | 83 // Out-of-bounds indexes should throw RangeError. |
| 87 testAtomicOp(Atomics.compareExchange, si32a, i, 0, name); | 84 [-1, 2, 100].forEach(function(i) { |
| 88 testAtomicOp(Atomics.load, si32a, i, 0, name); | 85 assertThrows(function() { Atomics.compareExchange(si32a, i, 0, 0); }, |
| 89 testAtomicOp(Atomics.store, si32a, i, 0, name); | 86 RangeError); |
| 90 testAtomicOp(Atomics.add, si32a, i, 0, name); | 87 assertThrows(function() { Atomics.load(si32a, i); }, RangeError); |
| 91 testAtomicOp(Atomics.sub, si32a, i, 0, name); | 88 assertThrows(function() { Atomics.store(si32a, i, 0); }, RangeError); |
| 92 testAtomicOp(Atomics.and, si32a, i, 0, name); | 89 assertThrows(function() { Atomics.add(si32a, i, 0); }, RangeError); |
| 93 testAtomicOp(Atomics.or, si32a, i, 0, name); | 90 assertThrows(function() { Atomics.sub(si32a, i, 0); }, RangeError); |
| 94 testAtomicOp(Atomics.xor, si32a, i, 0, name); | 91 assertThrows(function() { Atomics.and(si32a, i, 0); }, RangeError); |
| 95 testAtomicOp(Atomics.exchange, si32a, i, 0, name); | 92 assertThrows(function() { Atomics.or(si32a, i, 0); }, RangeError); |
| 93 assertThrows(function() { Atomics.xor(si32a, i, 0); }, RangeError); |
| 94 assertThrows(function() { Atomics.exchange(si32a, i, 0); }, RangeError); |
| 95 }, RangeError); |
| 96 |
| 97 // Out-of-bounds indexes for array with offset should throw RangeError. |
| 98 [-1, 1, 100].forEach(function(i) { |
| 99 assertThrows(function() { Atomics.compareExchange(si32a2, i, 0, 0); }); |
| 100 assertThrows(function() { Atomics.load(si32a2, i); }, RangeError); |
| 101 assertThrows(function() { Atomics.store(si32a2, i, 0); }, RangeError); |
| 102 assertThrows(function() { Atomics.add(si32a2, i, 0); }, RangeError); |
| 103 assertThrows(function() { Atomics.sub(si32a2, i, 0); }, RangeError); |
| 104 assertThrows(function() { Atomics.and(si32a2, i, 0); }, RangeError); |
| 105 assertThrows(function() { Atomics.or(si32a2, i, 0); }, RangeError); |
| 106 assertThrows(function() { Atomics.xor(si32a2, i, 0); }, RangeError); |
| 107 assertThrows(function() { Atomics.exchange(si32a2, i, 0); }, RangeError); |
| 96 }); | 108 }); |
| 97 | 109 |
| 98 // Out-of-bounds indexes should return undefined. | 110 // Monkey-patch length and make sure these functions still throw. |
| 99 // TODO(binji): Should these throw RangeError instead? | |
| 100 [-1, 2, 100].forEach(function(i) { | |
| 101 var name = String(i); | |
| 102 assertEquals(undefined, Atomics.compareExchange(si32a, i, 0, 0), name); | |
| 103 assertEquals(undefined, Atomics.load(si32a, i), name); | |
| 104 assertEquals(undefined, Atomics.store(si32a, i, 0), name); | |
| 105 assertEquals(undefined, Atomics.add(si32a, i, 0), name); | |
| 106 assertEquals(undefined, Atomics.sub(si32a, i, 0), name); | |
| 107 assertEquals(undefined, Atomics.and(si32a, i, 0), name); | |
| 108 assertEquals(undefined, Atomics.or(si32a, i, 0), name); | |
| 109 assertEquals(undefined, Atomics.xor(si32a, i, 0), name); | |
| 110 assertEquals(undefined, Atomics.exchange(si32a, i, 0), name); | |
| 111 }); | |
| 112 | |
| 113 // Out-of-bounds indexes for offset-array | |
| 114 [-1, 1, 100].forEach(function(i) { | |
| 115 var name = String(i); | |
| 116 assertEquals(undefined, Atomics.compareExchange(si32a2, i, 0, 0), name); | |
| 117 assertEquals(undefined, Atomics.load(si32a2, i), name); | |
| 118 assertEquals(undefined, Atomics.store(si32a2, i, 0), name); | |
| 119 assertEquals(undefined, Atomics.add(si32a2, i, 0), name); | |
| 120 assertEquals(undefined, Atomics.sub(si32a2, i, 0), name); | |
| 121 assertEquals(undefined, Atomics.and(si32a2, i, 0), name); | |
| 122 assertEquals(undefined, Atomics.or(si32a2, i, 0), name); | |
| 123 assertEquals(undefined, Atomics.xor(si32a2, i, 0), name); | |
| 124 assertEquals(undefined, Atomics.exchange(si32a2, i, 0), name); | |
| 125 }); | |
| 126 | |
| 127 // Monkey-patch length and make sure these functions still return undefined. | |
| 128 Object.defineProperty(si32a, 'length', {get: function() { return 1000; }}); | 111 Object.defineProperty(si32a, 'length', {get: function() { return 1000; }}); |
| 129 [2, 100].forEach(function(i) { | 112 [2, 100].forEach(function(i) { |
| 130 var name = String(i); | 113 assertThrows(function() { Atomics.compareExchange(si32a, i, 0, 0); }); |
| 131 assertEquals(undefined, Atomics.compareExchange(si32a, i, 0, 0), name); | 114 assertThrows(function() { Atomics.load(si32a, i); }); |
| 132 assertEquals(undefined, Atomics.load(si32a, i), name); | 115 assertThrows(function() { Atomics.store(si32a, i, 0); }); |
| 133 assertEquals(undefined, Atomics.store(si32a, i, 0), name); | 116 assertThrows(function() { Atomics.add(si32a, i, 0); }); |
| 134 assertEquals(undefined, Atomics.add(si32a, i, 0), name); | 117 assertThrows(function() { Atomics.sub(si32a, i, 0); }); |
| 135 assertEquals(undefined, Atomics.sub(si32a, i, 0), name); | 118 assertThrows(function() { Atomics.and(si32a, i, 0); }); |
| 136 assertEquals(undefined, Atomics.and(si32a, i, 0), name); | 119 assertThrows(function() { Atomics.or(si32a, i, 0); }); |
| 137 assertEquals(undefined, Atomics.or(si32a, i, 0), name); | 120 assertThrows(function() { Atomics.xor(si32a, i, 0); }); |
| 138 assertEquals(undefined, Atomics.xor(si32a, i, 0), name); | 121 assertThrows(function() { Atomics.exchange(si32a, i, 0); }); |
| 139 assertEquals(undefined, Atomics.exchange(si32a, i, 0), name); | |
| 140 }); | 122 }); |
| 141 })(); | 123 })(); |
| 142 | 124 |
| 143 (function TestGoodIndex() { | 125 (function TestGoodIndex() { |
| 144 var sab = new SharedArrayBuffer(64); | 126 var sab = new SharedArrayBuffer(64); |
| 145 var si32a = new Int32Array(sab); | 127 var si32a = new Int32Array(sab); |
| 146 var si32a2 = new Int32Array(sab, 32); | 128 var si32a2 = new Int32Array(sab, 32); |
| 147 | 129 |
| 130 var testOp = function(op, ia, index, expectedIndex, name) { |
| 131 for (var i = 0; i < ia.length; ++i) |
| 132 ia[i] = 22; |
| 133 |
| 134 ia[expectedIndex] = 0; |
| 135 assertEquals(0, op(ia, index, 0, 0), name); |
| 136 assertEquals(0, ia[expectedIndex], name); |
| 137 |
| 138 for (var i = 0; i < ia.length; ++i) { |
| 139 if (i == expectedIndex) continue; |
| 140 assertEquals(22, ia[i], name); |
| 141 } |
| 142 }; |
| 143 |
| 144 // These values all map to index 0 |
| 145 [-0, 0, 0.0, null, false].forEach(function(i) { |
| 146 var name = String(i); |
| 147 [si32a, si32a2].forEach(function(array) { |
| 148 testOp(Atomics.compareExchange, array, i, 0, name); |
| 149 testOp(Atomics.load, array, i, 0, name); |
| 150 testOp(Atomics.store, array, i, 0, name); |
| 151 testOp(Atomics.add, array, i, 0, name); |
| 152 testOp(Atomics.sub, array, i, 0, name); |
| 153 testOp(Atomics.and, array, i, 0, name); |
| 154 testOp(Atomics.or, array, i, 0, name); |
| 155 testOp(Atomics.xor, array, i, 0, name); |
| 156 testOp(Atomics.exchange, array, i, 0, name); |
| 157 }); |
| 158 }); |
| 159 |
| 160 // These values all map to index 3 |
| 148 var valueOf = {valueOf: function(){ return 3;}}; | 161 var valueOf = {valueOf: function(){ return 3;}}; |
| 149 var toString = {toString: function(){ return '3';}}; | 162 var toString = {toString: function(){ return '3';}}; |
| 150 | 163 [3, 3.0, '3', '3.0', valueOf, toString].forEach(function(i) { |
| 151 [3, 3.5, '3', '3.5', valueOf, toString].forEach(function(i) { | |
| 152 var name = String(i); | 164 var name = String(i); |
| 153 [si32a, si32a2].forEach(function(array) { | 165 [si32a, si32a2].forEach(function(array) { |
| 154 testAtomicOp(Atomics.compareExchange, array, i, 3, name); | 166 testOp(Atomics.compareExchange, array, i, 3, name); |
| 155 testAtomicOp(Atomics.load, array, i, 3, name); | 167 testOp(Atomics.load, array, i, 3, name); |
| 156 testAtomicOp(Atomics.store, array, i, 3, name); | 168 testOp(Atomics.store, array, i, 3, name); |
| 157 testAtomicOp(Atomics.add, array, i, 3, name); | 169 testOp(Atomics.add, array, i, 3, name); |
| 158 testAtomicOp(Atomics.sub, array, i, 3, name); | 170 testOp(Atomics.sub, array, i, 3, name); |
| 159 testAtomicOp(Atomics.and, array, i, 3, name); | 171 testOp(Atomics.and, array, i, 3, name); |
| 160 testAtomicOp(Atomics.or, array, i, 3, name); | 172 testOp(Atomics.or, array, i, 3, name); |
| 161 testAtomicOp(Atomics.xor, array, i, 3, name); | 173 testOp(Atomics.xor, array, i, 3, name); |
| 162 testAtomicOp(Atomics.exchange, array, i, 3, name); | 174 testOp(Atomics.exchange, array, i, 3, name); |
| 163 }) | 175 }); |
| 164 }); | 176 }); |
| 165 })(); | 177 })(); |
| 166 | 178 |
| 167 function clearArray(sab) { | 179 function clearArray(sab) { |
| 168 var ui8 = new Uint8Array(sab); | 180 var ui8 = new Uint8Array(sab); |
| 169 for (var i = 0; i < sab.byteLength; ++i) { | 181 for (var i = 0; i < sab.byteLength; ++i) { |
| 170 ui8[i] = 0; | 182 ui8[i] = 0; |
| 171 } | 183 } |
| 172 } | 184 } |
| 173 | 185 |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 // Exchange | 532 // Exchange |
| 521 sta[0] = val = 0x12; | 533 sta[0] = val = 0x12; |
| 522 operand = 0x22 + offset; | 534 operand = 0x22 + offset; |
| 523 valWrapped = t.toRange(operand); | 535 valWrapped = t.toRange(operand); |
| 524 assertEquals(val, Atomics.exchange(sta, 0, operand), name); | 536 assertEquals(val, Atomics.exchange(sta, 0, operand), name); |
| 525 assertEquals(valWrapped, sta[0], name); | 537 assertEquals(valWrapped, sta[0], name); |
| 526 } | 538 } |
| 527 | 539 |
| 528 }); | 540 }); |
| 529 })(); | 541 })(); |
| OLD | NEW |