OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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-simd --harmony-tostring --harmony-reflect | 5 // Flags: --harmony-simd --harmony-tostring --harmony-reflect |
6 // Flags: --allow-natives-syntax --expose-natives-as natives --noalways-opt | 6 // Flags: --allow-natives-syntax --expose-natives-as natives --noalways-opt |
7 | 7 |
8 var floatType = 0; | |
9 var intType = 1; | |
10 var boolType = 2; | |
11 | |
8 function lanesForType(typeName) { | 12 function lanesForType(typeName) { |
9 // The lane count follows the first 'x' in the type name, which begins with | 13 // The lane count follows the first 'x' in the type name, which begins with |
10 // 'float', 'int', or 'bool'. | 14 // 'float', 'int', or 'bool'. |
11 return Number.parseInt(typeName[typeName.indexOf('x') + 1]); | 15 return Number.parseInt(typeName.substr(typeName.indexOf('x') + 1)); |
12 } | 16 } |
13 | 17 |
14 | 18 |
19 // Creates an instance that has been zeroed, so it can be used for equality | |
20 // testing. | |
21 function createInstance(type) { | |
22 return SIMD[type](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); | |
23 } | |
24 | |
25 | |
15 function isValidSimdString(string, value, type, lanes) { | 26 function isValidSimdString(string, value, type, lanes) { |
16 var simdFn = SIMD[type], | 27 var simdFn = SIMD[type], |
17 parseFn = | 28 parseFn = |
18 type.indexOf('Float') === 0 ? Number.parseFloat : Number.parseInt, | 29 type.indexOf('Float') === 0 ? Number.parseFloat : Number.parseInt, |
19 indexOfOpenParen = string.indexOf('('); | 30 indexOfOpenParen = string.indexOf('('); |
20 // Check prefix (e.g. SIMD.Float32x4.) | 31 // Check prefix (e.g. SIMD.Float32x4.) |
21 if (string.substr(0, indexOfOpenParen) !== 'SIMD.' + type) | 32 if (string.substr(0, indexOfOpenParen) !== 'SIMD.' + type) |
22 return false; | 33 return false; |
23 // Remove type name (e.g. SIMD.Float32x4) and open parenthesis. | 34 // Remove type name (e.g. SIMD.Float32x4) and open parenthesis. |
24 string = string.substr(indexOfOpenParen + 1); | 35 string = string.substr(indexOfOpenParen + 1); |
25 var laneStrings = string.split(','); | 36 var laneStrings = string.split(','); |
26 if (laneStrings.length !== lanes) | 37 if (laneStrings.length !== lanes) |
27 return false; | 38 return false; |
28 for (var i = 0; i < lanes; i++) { | 39 for (var i = 0; i < lanes; i++) { |
29 var fromString = parseFn(laneStrings[i]), | 40 var fromString = parseFn(laneStrings[i]), |
30 fromValue = simdFn.extractLane(value, i); | 41 fromValue = simdFn.extractLane(value, i); |
31 if (Math.abs(fromString - fromValue) > Number.EPSILON) | 42 if (Math.abs(fromString - fromValue) > Number.EPSILON) |
32 return false; | 43 return false; |
33 } | 44 } |
34 return true; | 45 return true; |
35 } | 46 } |
36 | 47 |
37 | 48 |
38 // Test for structural equivalence. | 49 // Test different forms of constructor calls. |
39 function areEquivalent(type, lanes, a, b) { | |
40 var simdFn = SIMD[type]; | |
41 for (var i = 0; i < lanes; i++) { | |
42 if (simdFn.extractLane(a, i) !== simdFn.extractLane(b, i)) | |
43 return false; | |
44 } | |
45 return true; | |
46 } | |
47 | |
48 | |
49 var sameValue = natives.$sameValue; | |
50 var sameValueZero = natives.$sameValueZero; | |
51 | |
52 // Calls SameValue and SameValueZero and checks that their results match. Also | |
53 // checks the internal SameValue checks using Object freeze and defineProperty. | |
54 function sameValueBoth(a, b) { | |
55 var result = sameValue(a, b); | |
56 assertTrue(result === sameValueZero(a, b)); | |
57 return result; | |
58 } | |
59 | |
60 | |
61 // Calls SameValue and SameValueZero and checks that their results don't match. | |
62 function sameValueZeroOnly(a, b) { | |
63 var result = sameValueZero(a, b); | |
64 assertTrue(result && !sameValue(a, b)); | |
65 return result; | |
66 } | |
67 | |
68 | |
69 // Tests for the global SIMD object. | |
70 function TestSIMDObject() { | |
71 assertSame(typeof SIMD, 'object'); | |
72 assertSame(SIMD.constructor, Object); | |
73 assertSame(Object.getPrototypeOf(SIMD), Object.prototype); | |
74 assertSame(SIMD + "", "[object SIMD]"); | |
75 } | |
76 TestSIMDObject() | |
77 | |
78 // TestConstructor populates this with interesting values for the other tests. | |
79 var values; | |
80 | |
81 // Test different forms of constructor calls. This test populates 'values' with | |
82 // a variety of SIMD values as a side effect, which are used by other tests. | |
83 function TestConstructor(type, lanes) { | 50 function TestConstructor(type, lanes) { |
84 var simdFn = SIMD[type]; | 51 var simdFn = SIMD[type]; |
52 var instance = createInstance(type); | |
53 | |
85 assertFalse(Object === simdFn.prototype.constructor) | 54 assertFalse(Object === simdFn.prototype.constructor) |
86 assertFalse(simdFn === Object.prototype.constructor) | 55 assertFalse(simdFn === Object.prototype.constructor) |
87 assertSame(simdFn, simdFn.prototype.constructor) | 56 assertSame(simdFn, simdFn.prototype.constructor) |
88 | 57 |
89 values = [] | 58 assertSame(simdFn, instance.__proto__.constructor) |
90 | 59 assertSame(simdFn, Object(instance).__proto__.constructor) |
91 // The constructor expects values for all lanes. | 60 assertSame(simdFn.prototype, instance.__proto__) |
61 assertSame(simdFn.prototype, Object(instance).__proto__) | |
62 } | |
63 | |
64 function TestType(type, lanes) { | |
65 var simdFn = SIMD[type]; | |
66 var instance = createInstance(type); | |
67 var typeofString = type.charAt(0).toLowerCase() + type.slice(1); | |
68 | |
69 assertEquals(typeofString, typeof instance) | |
70 assertTrue(typeof instance === typeofString) | |
71 assertTrue(typeof Object(instance) === 'object') | |
72 assertEquals(null, %_ClassOf(instance)) | |
73 assertEquals(type, %_ClassOf(Object(instance))) | |
74 } | |
75 | |
76 | |
77 function TestPrototype(type, lanes) { | |
78 var simdFn = SIMD[type]; | |
79 var instance = createInstance(type); | |
80 | |
81 assertSame(Object.prototype, simdFn.prototype.__proto__) | |
82 assertSame(simdFn.prototype, instance.__proto__) | |
83 assertSame(simdFn.prototype, Object(instance).__proto__) | |
84 } | |
85 | |
86 | |
87 function TestValueOf(type, lanes) { | |
88 var simdFn = SIMD[type]; | |
89 var instance = createInstance(type); | |
90 | |
91 assertTrue(instance === Object(instance).valueOf()) | |
92 assertTrue(instance === instance.valueOf()) | |
93 assertTrue(simdFn.prototype.valueOf.call(Object(instance)) === instance) | |
94 assertTrue(simdFn.prototype.valueOf.call(instance) === instance) | |
95 } | |
96 | |
97 | |
98 function TestGet(type, lanes) { | |
99 var simdFn = SIMD[type]; | |
100 var instance = createInstance(type); | |
101 | |
102 assertEquals(undefined, instance.a) | |
103 assertEquals(undefined, instance["a" + "b"]) | |
104 assertEquals(undefined, instance["" + "1"]) | |
105 assertEquals(undefined, instance[42]) | |
106 } | |
107 | |
108 | |
109 function TestToBoolean(type, lanes) { | |
110 var simdFn = SIMD[type]; | |
111 var instance = createInstance(type); | |
112 | |
113 assertTrue(Boolean(Object(instance))) | |
114 assertFalse(!Object(instance)) | |
115 assertTrue(Boolean(instance).valueOf()) | |
116 assertFalse(!instance) | |
117 assertTrue(!!instance) | |
118 assertTrue(instance && true) | |
119 assertFalse(!instance && false) | |
120 assertTrue(!instance || true) | |
121 assertEquals(1, instance ? 1 : 2) | |
122 assertEquals(2, !instance ? 1 : 2) | |
123 if (!instance) assertUnreachable(); | |
124 if (instance) {} else assertUnreachable(); | |
125 } | |
126 | |
127 | |
128 function TestToString(type, lanes) { | |
129 var simdFn = SIMD[type]; | |
130 var instance = createInstance(type); | |
131 | |
132 assertEquals(instance.toString(), String(instance)) | |
133 assertTrue(isValidSimdString(instance.toString(), instance, type, lanes)) | |
134 assertTrue( | |
135 isValidSimdString(Object(instance).toString(), instance, type, lanes)) | |
136 assertTrue(isValidSimdString( | |
137 simdFn.prototype.toString.call(instance), instance, type, lanes)) | |
138 } | |
139 | |
140 | |
141 function TestToNumber(type, lanes) { | |
142 var simdFn = SIMD[type]; | |
143 var instance = createInstance(type); | |
144 | |
145 assertThrows(function() { Number(Object(instance)) }, TypeError) | |
146 assertThrows(function() { +Object(instance) }, TypeError) | |
147 assertThrows(function() { Number(instance) }, TypeError) | |
148 assertThrows(function() { instance + 0 }, TypeError) | |
149 } | |
150 | |
151 | |
152 function TestCoercions(type, lanes) { | |
153 var simdFn = SIMD[type]; | |
154 var instance = createInstance(type); | |
155 // Test that setting a lane to value 'a' results in a lane with value 'b'. | |
156 function test(a, b) { | |
157 for (var i = 0; i < lanes; i++) { | |
158 var ainstance = simdFn.replaceLane(instance, i, a); | |
159 var lane_value = simdFn.extractLane(ainstance, i); | |
160 assertSame(b, lane_value); | |
161 } | |
162 } | |
163 | |
92 switch (type) { | 164 switch (type) { |
93 case 'Float32x4': | 165 case 'Float32x4': |
94 // The constructor expects values for all lanes. | 166 test(0, 0); |
95 assertThrows(function () { simdFn() }, TypeError) | 167 test(-0, -0); |
96 assertThrows(function () { simdFn(0) }, TypeError) | 168 test(NaN, NaN); |
97 assertThrows(function () { simdFn(0, 1) }, TypeError) | 169 test(null, 0); |
98 assertThrows(function () { simdFn(0, 1, 2) }, TypeError) | 170 test(undefined, NaN); |
99 | 171 test("5.25", 5.25); |
100 values.push(simdFn(1, 2, 3, 4)) | 172 test(Number.MAX_VALUE, Infinity); |
101 values.push(simdFn(1, 2, 3, 4)) // test structural equivalence | 173 test(-Number.MAX_VALUE, -Infinity); |
102 values.push(simdFn(-0, NaN, 0, 0.5)) | 174 test(Number.MIN_VALUE, 0); |
103 values.push(simdFn(-0, NaN, 0, 0.5)) // test structural equivalence | 175 break; |
104 values.push(simdFn(3, 2, 1, 0)) | 176 case 'Int32x4': |
105 values.push(simdFn(0, 0, 0, 0)) | 177 test(Infinity, 0); |
106 break | 178 test(-Infinity, 0); |
107 } | 179 test(NaN, 0); |
108 for (var i in values) { | 180 test(0, 0); |
109 assertSame(simdFn, values[i].__proto__.constructor) | 181 test(-0, 0); |
110 assertSame(simdFn, Object(values[i]).__proto__.constructor) | 182 test(Number.MIN_VALUE, 0); |
111 assertSame(simdFn.prototype, values[i].__proto__) | 183 test(-Number.MIN_VALUE, 0); |
112 assertSame(simdFn.prototype, Object(values[i]).__proto__) | 184 test(0.1, 0); |
113 } | 185 test(-0.1, 0); |
114 } | 186 test(1, 1); |
115 | 187 test(1.1, 1); |
116 | 188 test(-1, -1); |
117 function TestType(type, lanes) { | 189 test(-1.6, -1); |
118 var typeofString = type.charAt(0).toLowerCase() + type.slice(1); | 190 test(2147483647, 2147483647); |
119 for (var i in values) { | 191 test(2147483648, -2147483648); |
120 assertEquals(typeofString, typeof values[i]) | 192 test(2147483649, -2147483647); |
121 assertTrue(typeof values[i] === typeofString) | 193 test(4294967295, -1); |
122 assertTrue(typeof Object(values[i]) === 'object') | 194 test(4294967296, 0); |
123 assertEquals(null, %_ClassOf(values[i])) | 195 test(4294967297, 1); |
124 assertEquals(type, %_ClassOf(Object(values[i]))) | 196 break; |
125 } | 197 case 'Int16x8': |
126 } | 198 test(Infinity, 0); |
127 | 199 test(-Infinity, 0); |
128 | 200 test(NaN, 0); |
129 function TestPrototype(type, lanes) { | 201 test(0, 0); |
130 var simdFn = SIMD[type]; | 202 test(-0, 0); |
131 assertSame(Object.prototype, simdFn.prototype.__proto__) | 203 test(Number.MIN_VALUE, 0); |
132 for (var i in values) { | 204 test(-Number.MIN_VALUE, 0); |
133 assertSame(simdFn.prototype, values[i].__proto__) | 205 test(0.1, 0); |
134 assertSame(simdFn.prototype, Object(values[i]).__proto__) | 206 test(-0.1, 0); |
135 } | 207 test(1, 1); |
136 } | 208 test(1.1, 1); |
137 | 209 test(-1, -1); |
138 | 210 test(-1.6, -1); |
139 function TestValueOf(type, lanes) { | 211 test(32767, 32767); |
140 var simdFn = SIMD[type]; | 212 test(32768, -32768); |
141 for (var i in values) { | 213 test(32769, -32767); |
142 assertTrue(values[i] === Object(values[i]).valueOf()) | 214 test(65535, -1); |
143 assertTrue(values[i] === values[i].valueOf()) | 215 test(65536, 0); |
144 assertTrue(simdFn.prototype.valueOf.call(Object(values[i])) === values[i]) | 216 test(65537, 1); |
145 assertTrue(simdFn.prototype.valueOf.call(values[i]) === values[i]) | 217 break; |
146 } | 218 case 'Int8x16': |
147 } | 219 test(Infinity, 0); |
148 | 220 test(-Infinity, 0); |
149 | 221 test(NaN, 0); |
150 function TestGet(type, lanes) { | 222 test(0, 0); |
151 var simdFn = SIMD[type]; | 223 test(-0, 0); |
152 for (var i in values) { | 224 test(Number.MIN_VALUE, 0); |
153 assertEquals(undefined, values[i].a) | 225 test(-Number.MIN_VALUE, 0); |
154 assertEquals(undefined, values[i]["a" + "b"]) | 226 test(0.1, 0); |
155 assertEquals(undefined, values[i]["" + "1"]) | 227 test(-0.1, 0); |
156 assertEquals(undefined, values[i][42]) | 228 test(1, 1); |
157 } | 229 test(1.1, 1); |
158 } | 230 test(-1, -1); |
159 | 231 test(-1.6, -1); |
160 | 232 test(127, 127); |
161 function TestToBoolean(type, lanes) { | 233 test(128, -128); |
162 for (var i in values) { | 234 test(129, -127); |
163 assertTrue(Boolean(Object(values[i]))) | 235 test(255, -1); |
164 assertFalse(!Object(values[i])) | 236 test(256, 0); |
165 assertTrue(Boolean(values[i]).valueOf()) | 237 test(257, 1); |
166 assertFalse(!values[i]) | 238 break; |
167 assertTrue(!!values[i]) | 239 case 'Bool32x4': |
168 assertTrue(values[i] && true) | 240 case 'Bool16x8': |
169 assertFalse(!values[i] && false) | 241 case 'Bool8x16': |
170 assertTrue(!values[i] || true) | 242 test(true, true); |
171 assertEquals(1, values[i] ? 1 : 2) | 243 test(false, false); |
172 assertEquals(2, !values[i] ? 1 : 2) | 244 test(0, false); |
173 if (!values[i]) assertUnreachable(); | 245 test(1, true); |
174 if (values[i]) {} else assertUnreachable(); | 246 test(0.1, true); |
175 } | 247 test(NaN, false); |
176 } | 248 test(null, false); |
177 | 249 test("", false); |
178 | 250 test("false", true); |
179 function TestToString(type, lanes) { | 251 break; |
180 var simdFn = SIMD[type]; | |
181 for (var i in values) { | |
182 assertEquals(values[i].toString(), String(values[i])) | |
183 assertTrue(isValidSimdString(values[i].toString(), values[i], type, lanes)) | |
184 assertTrue( | |
185 isValidSimdString(Object(values[i]).toString(), values[i], type, lanes)) | |
186 assertTrue(isValidSimdString( | |
187 simdFn.prototype.toString.call(values[i]), values[i], type, lanes)) | |
188 } | |
189 } | |
190 | |
191 | |
192 function TestToNumber(type, lanes) { | |
193 for (var i in values) { | |
194 assertThrows(function() { Number(Object(values[i])) }, TypeError) | |
195 assertThrows(function() { +Object(values[i]) }, TypeError) | |
196 assertThrows(function() { Number(values[i]) }, TypeError) | |
197 assertThrows(function() { values[i] + 0 }, TypeError) | |
198 } | 252 } |
199 } | 253 } |
200 | 254 |
201 | 255 |
202 function TestEquality(type, lanes) { | 256 function TestEquality(type, lanes) { |
257 var simdFn = SIMD[type]; | |
258 var instance = createInstance(type); | |
259 | |
203 // Every SIMD value should equal itself, and non-strictly equal its wrapper. | 260 // Every SIMD value should equal itself, and non-strictly equal its wrapper. |
204 for (var i in values) { | 261 assertSame(instance, instance) |
205 assertSame(values[i], values[i]) | 262 assertEquals(instance, instance) |
206 assertEquals(values[i], values[i]) | 263 assertTrue(Object.is(instance, instance)) |
207 assertTrue(Object.is(values[i], values[i])) | 264 assertTrue(instance === instance) |
208 assertTrue(values[i] === values[i]) | 265 assertTrue(instance == instance) |
209 assertTrue(values[i] == values[i]) | 266 assertFalse(instance === Object(instance)) |
210 assertFalse(values[i] === Object(values[i])) | 267 assertFalse(Object(instance) === instance) |
211 assertFalse(Object(values[i]) === values[i]) | 268 assertFalse(instance == Object(instance)) |
212 assertFalse(values[i] == Object(values[i])) | 269 assertFalse(Object(instance) == instance) |
213 assertFalse(Object(values[i]) == values[i]) | 270 assertTrue(instance === instance.valueOf()) |
214 assertTrue(values[i] === values[i].valueOf()) | 271 assertTrue(instance.valueOf() === instance) |
215 assertTrue(values[i].valueOf() === values[i]) | 272 assertTrue(instance == instance.valueOf()) |
216 assertTrue(values[i] == values[i].valueOf()) | 273 assertTrue(instance.valueOf() == instance) |
217 assertTrue(values[i].valueOf() == values[i]) | 274 assertFalse(Object(instance) === Object(instance)) |
218 assertFalse(Object(values[i]) === Object(values[i])) | 275 assertEquals(Object(instance).valueOf(), Object(instance).valueOf()) |
219 assertEquals(Object(values[i]).valueOf(), Object(values[i]).valueOf()) | |
220 } | |
221 | |
222 // Test structural equivalence. | |
223 for (var i = 0; i < values.length; i++) { | |
224 for (var j = i + 1; j < values.length; j++) { | |
225 var a = values[i], b = values[j], | |
226 equivalent = areEquivalent(type, lanes, a, b); | |
227 assertSame(equivalent, a == b); | |
228 assertSame(equivalent, a === b); | |
229 } | |
230 } | |
231 | 276 |
232 // SIMD values should not be equal to any other kind of object. | 277 // SIMD values should not be equal to any other kind of object. |
rossberg
2015/07/29 14:37:56
Can you add tests involving two different SIMD typ
bbudge
2015/07/30 13:46:58
Good idea. Done.
| |
233 var others = [347, 1.275, NaN, "string", null, undefined, {}, function() {}] | 278 var others = [347, 1.275, NaN, "string", null, undefined, {}, function() {}] |
234 for (var i in values) { | 279 for (var j in others) { |
235 for (var j in others) { | 280 assertFalse(instance === others[j]) |
236 assertFalse(values[i] === others[j]) | 281 assertFalse(others[j] === instance) |
237 assertFalse(others[j] === values[i]) | 282 assertFalse(instance == others[j]) |
238 assertFalse(values[i] == others[j]) | 283 assertFalse(others[j] == instance) |
239 assertFalse(others[j] == values[i]) | 284 } |
285 | |
286 // Test that f(a, b) is the same as f(SIMD(a), SIMD(b)) for equality and | |
287 // strict equality, at every lane. | |
288 function test(a, b) { | |
289 for (var i = 0; i < lanes; i++) { | |
290 var aval = simdFn.replaceLane(instance, i, a); | |
291 var bval = simdFn.replaceLane(instance, i, b); | |
292 assertSame(a == b, aval == bval); | |
293 assertSame(a === b, aval === bval); | |
240 } | 294 } |
241 } | 295 } |
242 } | 296 |
243 | 297 switch (type) { |
298 case 'Float32x4': | |
299 test(1, 2.5); | |
300 test(1, 1); | |
301 test(0, 0); | |
302 test(-0, +0); | |
303 test(+0, -0); | |
304 test(-0, -0); | |
305 test(0, NaN); | |
306 test(NaN, NaN); | |
307 break; | |
308 case 'Int32x4': | |
309 case 'Int16x8': | |
310 case 'Int8x16': | |
311 test(1, 2); | |
312 test(1, 1); | |
313 test(1, -1); | |
314 break; | |
315 case 'Bool32x4': | |
316 case 'Bool16x8': | |
317 case 'Bool8x16': | |
318 test(true, false); | |
319 test(false, true); | |
320 break; | |
321 } | |
322 } | |
244 | 323 |
245 function TestSameValue(type, lanes) { | 324 function TestSameValue(type, lanes) { |
rossberg
2015/07/29 14:37:56
Same here.
bbudge
2015/07/30 13:46:58
Done.
| |
246 // SIMD value types. | 325 var simdFn = SIMD[type]; |
247 // All lanes checked. | 326 var instance = createInstance(type); |
248 // TODO(bbudge): use loops to test lanes when replaceLane is defined. | 327 var sameValue = natives.$sameValue; |
249 assertTrue(sameValueBoth(SIMD.Float32x4(1, 2, 3, 4), | 328 var sameValueZero = natives.$sameValueZero; |
250 SIMD.Float32x4(1, 2, 3, 4))); | 329 |
251 assertFalse(sameValueBoth(SIMD.Float32x4(1, 2, 3, 4), | 330 // Test that f(a, b) is the same as f(SIMD(a), SIMD(b)) for sameValue and |
252 SIMD.Float32x4(NaN, 2, 3, 4))); | 331 // sameValueZero, at every lane. |
253 assertFalse(sameValueBoth(SIMD.Float32x4(1, 2, 3, 4), | 332 function test(a, b) { |
254 SIMD.Float32x4(1, NaN, 3, 4))); | 333 for (var i = 0; i < lanes; i++) { |
255 assertFalse(sameValueBoth(SIMD.Float32x4(1, 2, 3, 4), | 334 var aval = simdFn.replaceLane(instance, i, a); |
256 SIMD.Float32x4(1, 2, NaN, 4))); | 335 var bval = simdFn.replaceLane(instance, i, b); |
257 assertFalse(sameValueBoth(SIMD.Float32x4(1, 2, 3, 4), | 336 assertSame(sameValue(a, b), sameValue(aval, bval)); |
258 SIMD.Float32x4(1, 2, 3, NaN))); | 337 assertSame(sameValueZero(a, b), sameValueZero(aval, bval)); |
259 // Special values. | 338 } |
260 // TODO(bbudge): use loops to test lanes when replaceLane is defined. | 339 } |
261 assertTrue(sameValueBoth(SIMD.Float32x4(NaN, 2, 3, 4), | 340 |
262 SIMD.Float32x4(NaN, 2, 3, 4))); | 341 switch (type) { |
263 assertTrue(sameValueBoth(SIMD.Float32x4(+0, 2, 3, 4), | 342 case 'Float32x4': |
264 SIMD.Float32x4(+0, 2, 3, 4))); | 343 test(1, 2.5); |
265 assertTrue(sameValueBoth(SIMD.Float32x4(-0, 2, 3, 4), | 344 test(1, 1); |
266 SIMD.Float32x4(-0, 2, 3, 4))); | 345 test(0, 0); |
267 assertTrue(sameValueZeroOnly(SIMD.Float32x4(+0, 2, 3, 4), | 346 test(-0, +0); |
268 SIMD.Float32x4(-0, 2, 3, 4))); | 347 test(+0, -0); |
269 assertTrue(sameValueZeroOnly(SIMD.Float32x4(-0, 2, 3, 4), | 348 test(-0, -0); |
270 SIMD.Float32x4(+0, 2, 3, 4))); | 349 test(0, NaN); |
350 test(NaN, NaN); | |
351 break; | |
352 case 'Int32x4': | |
353 case 'Int16x8': | |
354 case 'Int8x16': | |
355 test(1, 2); | |
356 test(1, 1); | |
357 test(1, -1); | |
358 break; | |
359 case 'Bool32x4': | |
360 case 'Bool16x8': | |
361 case 'Bool8x16': | |
362 test(true, false); | |
363 test(false, true); | |
364 break; | |
365 } | |
271 } | 366 } |
272 | 367 |
273 | 368 |
274 function TestComparison(type, lanes) { | 369 function TestComparison(type, lanes) { |
275 var a = values[0], b = values[1]; | 370 var simdFn = SIMD[type]; |
371 var a = createInstance(type), b = createInstance(type); | |
rossberg
2015/07/29 14:37:56
Again it would be good to check the matrix of SIMD
bbudge
2015/07/30 13:46:59
Done.
| |
276 | 372 |
277 function lt() { a < b; } | 373 function lt() { a < b; } |
278 function gt() { a > b; } | 374 function gt() { a > b; } |
279 function le() { a <= b; } | 375 function le() { a <= b; } |
280 function ge() { a >= b; } | 376 function ge() { a >= b; } |
281 function lt_same() { a < a; } | 377 function lt_same() { a < a; } |
282 function gt_same() { a > a; } | 378 function gt_same() { a > a; } |
283 function le_same() { a <= a; } | 379 function le_same() { a <= a; } |
284 function ge_same() { a >= a; } | 380 function ge_same() { a >= a; } |
285 | 381 |
286 var throwFuncs = [lt, gt, le, ge, lt_same, gt_same, le_same, ge_same]; | 382 var throwFuncs = [lt, gt, le, ge, lt_same, gt_same, le_same, ge_same]; |
287 | |
288 for (var f of throwFuncs) { | 383 for (var f of throwFuncs) { |
289 assertThrows(f, TypeError); | 384 assertThrows(f, TypeError); |
290 %OptimizeFunctionOnNextCall(f); | 385 %OptimizeFunctionOnNextCall(f); |
291 assertThrows(f, TypeError); | 386 assertThrows(f, TypeError); |
292 assertThrows(f, TypeError); | 387 assertThrows(f, TypeError); |
293 } | 388 } |
294 } | 389 } |
295 | 390 |
296 | 391 |
297 // Test SIMD value wrapping/boxing over non-builtins. | 392 // Test SIMD value wrapping/boxing over non-builtins. |
298 function TestCall(type, lanes) { | 393 function TestCall(type, lanes) { |
299 var simdFn = SIMD[type]; | 394 var simdFn = SIMD[type]; |
395 var instance = createInstance(type); | |
300 simdFn.prototype.getThisProto = function () { | 396 simdFn.prototype.getThisProto = function () { |
301 return Object.getPrototypeOf(this); | 397 return Object.getPrototypeOf(this); |
302 } | 398 } |
303 for (var i in values) { | 399 assertTrue(instance.getThisProto() === simdFn.prototype) |
304 assertTrue(values[i].getThisProto() === simdFn.prototype) | |
305 } | |
306 } | 400 } |
307 | 401 |
308 | 402 |
309 function TestAsSetKey(type, lanes, set) { | 403 function TestAsSetKey(type, lanes, set) { |
404 var simdFn = SIMD[type]; | |
405 var instance = createInstance(type); | |
406 | |
310 function test(set, key) { | 407 function test(set, key) { |
311 assertFalse(set.has(key)); | 408 assertFalse(set.has(key)); |
312 assertFalse(set.delete(key)); | 409 assertFalse(set.delete(key)); |
313 if (!(set instanceof WeakSet)) { | 410 if (!(set instanceof WeakSet)) { |
314 assertSame(set, set.add(key)); | 411 assertSame(set, set.add(key)); |
315 assertTrue(set.has(key)); | 412 assertTrue(set.has(key)); |
316 assertTrue(set.delete(key)); | 413 assertTrue(set.delete(key)); |
317 } else { | 414 } else { |
318 // SIMD values can't be used as keys in WeakSets. | 415 // SIMD values can't be used as keys in WeakSets. |
319 assertThrows(function() { set.add(key) }); | 416 assertThrows(function() { set.add(key) }); |
320 } | 417 } |
321 assertFalse(set.has(key)); | 418 assertFalse(set.has(key)); |
322 assertFalse(set.delete(key)); | 419 assertFalse(set.delete(key)); |
323 assertFalse(set.has(key)); | 420 assertFalse(set.has(key)); |
324 } | 421 } |
325 | 422 |
326 for (var i in values) { | 423 test(set, instance); |
rossberg
2015/07/29 14:37:56
This now only tests for a zeroed value, which seem
bbudge
2015/07/30 13:46:58
I changed createInstance to create slightly more i
| |
327 test(set, values[i]); | |
328 } | |
329 } | 424 } |
330 | 425 |
331 | 426 |
332 function TestAsMapKey(type, lanes, map) { | 427 function TestAsMapKey(type, lanes, map) { |
428 var simdFn = SIMD[type]; | |
429 var instance = createInstance(type); | |
430 | |
333 function test(map, key, value) { | 431 function test(map, key, value) { |
334 assertFalse(map.has(key)); | 432 assertFalse(map.has(key)); |
335 assertSame(undefined, map.get(key)); | 433 assertSame(undefined, map.get(key)); |
336 assertFalse(map.delete(key)); | 434 assertFalse(map.delete(key)); |
337 if (!(map instanceof WeakMap)) { | 435 if (!(map instanceof WeakMap)) { |
338 assertSame(map, map.set(key, value)); | 436 assertSame(map, map.set(key, value)); |
339 assertSame(value, map.get(key)); | 437 assertSame(value, map.get(key)); |
340 assertTrue(map.has(key)); | 438 assertTrue(map.has(key)); |
341 assertTrue(map.delete(key)); | 439 assertTrue(map.delete(key)); |
342 } else { | 440 } else { |
343 // SIMD values can't be used as keys in WeakMaps. | 441 // SIMD values can't be used as keys in WeakMaps. |
344 assertThrows(function() { map.set(key, value) }); | 442 assertThrows(function() { map.set(key, value) }); |
345 } | 443 } |
346 assertFalse(map.has(key)); | 444 assertFalse(map.has(key)); |
347 assertSame(undefined, map.get(key)); | 445 assertSame(undefined, map.get(key)); |
348 assertFalse(map.delete(key)); | 446 assertFalse(map.delete(key)); |
349 assertFalse(map.has(key)); | 447 assertFalse(map.has(key)); |
350 assertSame(undefined, map.get(key)); | 448 assertSame(undefined, map.get(key)); |
351 } | 449 } |
352 | 450 |
353 for (var i in values) { | 451 test(map, instance, {}); |
rossberg
2015/07/29 14:37:56
Similarly here.
bbudge
2015/07/30 13:46:58
Done.
| |
354 test(map, values[i], {}); | |
355 } | |
356 } | 452 } |
357 | 453 |
358 | 454 |
359 // Test SIMD type with Harmony reflect-apply. | 455 // Test SIMD type with Harmony reflect-apply. |
360 function TestReflectApply(type) { | 456 function TestReflectApply(type) { |
457 var simdFn = SIMD[type]; | |
458 var instance = createInstance(type); | |
459 | |
361 function returnThis() { return this; } | 460 function returnThis() { return this; } |
362 function returnThisStrict() { 'use strict'; return this; } | 461 function returnThisStrict() { 'use strict'; return this; } |
363 function noop() {} | 462 function noop() {} |
364 function noopStrict() { 'use strict'; } | 463 function noopStrict() { 'use strict'; } |
365 var R = void 0; | 464 var R = void 0; |
366 | 465 |
367 for (var i in values) { | 466 assertSame(SIMD[type].prototype, |
368 assertSame(SIMD[type].prototype, | 467 Object.getPrototypeOf( |
369 Object.getPrototypeOf( | 468 Reflect.apply(returnThis, instance, []))); |
370 Reflect.apply(returnThis, values[i], []))); | 469 assertSame(instance, Reflect.apply(returnThisStrict, instance, [])); |
371 assertSame(values[i], Reflect.apply(returnThisStrict, values[i], [])); | |
372 | 470 |
373 assertThrows( | 471 assertThrows( |
374 function() { 'use strict'; Reflect.apply(values[i]); }, TypeError); | 472 function() { 'use strict'; Reflect.apply(instance); }, TypeError); |
375 assertThrows( | 473 assertThrows( |
376 function() { Reflect.apply(values[i]); }, TypeError); | 474 function() { Reflect.apply(instance); }, TypeError); |
377 assertThrows( | 475 assertThrows( |
378 function() { Reflect.apply(noopStrict, R, values[i]); }, TypeError); | 476 function() { Reflect.apply(noopStrict, R, instance); }, TypeError); |
379 assertThrows( | 477 assertThrows( |
380 function() { Reflect.apply(noop, R, values[i]); }, TypeError); | 478 function() { Reflect.apply(noop, R, instance); }, TypeError); |
381 } | |
382 } | 479 } |
383 | 480 |
384 | 481 |
385 function TestSIMDTypes() { | 482 function TestSIMDTypes() { |
386 var types = [ 'Float32x4' ]; | 483 var types = ['Float32x4', 'Int32x4', 'Bool32x4', |
484 'Int16x8', 'Bool16x8', | |
485 'Int8x16', 'Bool8x16']; | |
387 for (var i = 0; i < types.length; ++i) { | 486 for (var i = 0; i < types.length; ++i) { |
388 var type = types[i], | 487 var type = types[i], |
389 lanes = lanesForType(type); | 488 lanes = lanesForType(type); |
390 TestConstructor(type, lanes); | 489 TestConstructor(type, lanes); |
391 TestType(type, lanes); | 490 TestType(type, lanes); |
392 TestPrototype(type, lanes); | 491 TestPrototype(type, lanes); |
393 TestValueOf(type, lanes); | 492 TestValueOf(type, lanes); |
394 TestGet(type, lanes); | 493 TestGet(type, lanes); |
395 TestToBoolean(type, lanes); | 494 TestToBoolean(type, lanes); |
396 TestToString(type, lanes); | 495 TestToString(type, lanes); |
397 TestToNumber(type, lanes); | 496 TestToNumber(type, lanes); |
497 TestCoercions(type, lanes); | |
398 TestEquality(type, lanes); | 498 TestEquality(type, lanes); |
399 TestSameValue(type, lanes); | 499 TestSameValue(type, lanes); |
400 TestComparison(type, lanes); | 500 TestComparison(type, lanes); |
401 TestCall(type, lanes); | 501 TestCall(type, lanes); |
402 TestAsSetKey(type, lanes, new Set); | 502 TestAsSetKey(type, lanes, new Set); |
403 TestAsSetKey(type, lanes, new WeakSet); | 503 TestAsSetKey(type, lanes, new WeakSet); |
404 TestAsMapKey(type, lanes, new Map); | 504 TestAsMapKey(type, lanes, new Map); |
405 TestAsMapKey(type, lanes, new WeakMap); | 505 TestAsMapKey(type, lanes, new WeakMap); |
406 TestReflectApply(type); | 506 TestReflectApply(type); |
407 } | 507 } |
408 } | 508 } |
409 TestSIMDTypes(); | 509 TestSIMDTypes(); |
510 | |
511 // Tests for the global SIMD object. | |
512 function TestSIMDObject() { | |
513 assertSame(typeof SIMD, 'object'); | |
514 assertSame(SIMD.constructor, Object); | |
515 assertSame(Object.getPrototypeOf(SIMD), Object.prototype); | |
516 assertSame(SIMD + "", "[object SIMD]"); | |
517 // The SIMD object is mutable. | |
518 SIMD.foo = "foo"; | |
519 assertSame(SIMD.foo, "foo"); | |
520 delete SIMD.foo; | |
521 delete SIMD.Bool8x16; | |
522 assertSame(SIMD.Bool8x16, undefined); | |
523 } | |
524 TestSIMDObject() | |
OLD | NEW |