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 |