OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 // Flags: --harmony-simd | |
6 // Flags: --allow-natives-syntax --expose-natives-as natives --noalways-opt | |
7 | |
8 function lanesForType(typeName) { | |
9 // The lane count follows the first 'x' in the type name, which begins with | |
10 // 'float', 'int', or 'bool'. | |
11 return Number.parseInt(typeName.substr(typeName.indexOf('x') + 1)); | |
12 } | |
13 | |
14 | |
15 // Creates an instance that has been zeroed, so it can be used for equality | |
16 // testing. | |
17 function createInstance(type) { | |
18 // Provide enough parameters for the longest type (currently 16). It's | |
19 // important that instances be consistent to better test that different SIMD | |
20 // types can't be compared and are never equal or the same in any sense. | |
21 return SIMD[type](0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); | |
22 } | |
23 | |
24 | |
25 function isValidSimdString(string, value, type, lanes) { | |
26 var simdFn = SIMD[type], | |
27 parseFn = | |
28 type.indexOf('Float') === 0 ? Number.parseFloat : Number.parseInt, | |
29 indexOfOpenParen = string.indexOf('('); | |
30 // Check prefix (e.g. SIMD.Float32x4.) | |
31 if (string.substr(0, indexOfOpenParen) !== 'SIMD.' + type) | |
32 return false; | |
33 // Remove type name (e.g. SIMD.Float32x4) and open parenthesis. | |
34 string = string.substr(indexOfOpenParen + 1); | |
35 var laneStrings = string.split(','); | |
36 if (laneStrings.length !== lanes) | |
37 return false; | |
38 for (var i = 0; i < lanes; i++) { | |
39 var fromString = parseFn(laneStrings[i]), | |
40 fromValue = simdFn.extractLane(value, i); | |
41 if (Math.abs(fromString - fromValue) > Number.EPSILON) | |
42 return false; | |
43 } | |
44 return true; | |
45 } | |
46 | |
47 | |
48 var simdTypeNames = ['Float32x4', 'Int32x4', 'Uint32x4', 'Bool32x4', | |
49 'Int16x8', 'Uint16x8', 'Bool16x8', | |
50 'Int8x16', 'Uint8x16', 'Bool8x16']; | |
51 | |
52 var nonSimdValues = [347, 1.275, NaN, "string", null, undefined, {}, | |
53 function() {}]; | |
54 | |
55 function checkTypeMatrix(type, fn) { | |
56 // Check against non-SIMD types. | |
57 nonSimdValues.forEach(fn); | |
58 // Check against SIMD values of a different type. | |
59 for (var i = 0; i < simdTypeNames.length; i++) { | |
60 var otherType = simdTypeNames[i]; | |
61 if (type != otherType) fn(createInstance(otherType)); | |
62 } | |
63 } | |
64 | |
65 | |
66 // Test different forms of constructor calls. | |
67 function TestConstructor(type, lanes) { | |
68 var simdFn = SIMD[type]; | |
69 var instance = createInstance(type); | |
70 | |
71 assertFalse(Object === simdFn.prototype.constructor) | |
72 assertFalse(simdFn === Object.prototype.constructor) | |
73 assertSame(simdFn, simdFn.prototype.constructor) | |
74 | |
75 assertSame(simdFn, instance.__proto__.constructor) | |
76 assertSame(simdFn, Object(instance).__proto__.constructor) | |
77 assertSame(simdFn.prototype, instance.__proto__) | |
78 assertSame(simdFn.prototype, Object(instance).__proto__) | |
79 } | |
80 | |
81 | |
82 function TestType(type, lanes) { | |
83 var simdFn = SIMD[type]; | |
84 var instance = createInstance(type); | |
85 var typeofString = type.charAt(0).toLowerCase() + type.slice(1); | |
86 | |
87 assertEquals(typeofString, typeof instance) | |
88 assertTrue(typeof instance === typeofString) | |
89 assertTrue(typeof Object(instance) === 'object') | |
90 assertEquals(null, %_ClassOf(instance)) | |
91 assertEquals(type, %_ClassOf(Object(instance))) | |
92 } | |
93 | |
94 | |
95 function TestPrototype(type, lanes) { | |
96 var simdFn = SIMD[type]; | |
97 var instance = createInstance(type); | |
98 | |
99 assertSame(Object.prototype, simdFn.prototype.__proto__) | |
100 assertSame(simdFn.prototype, instance.__proto__) | |
101 assertSame(simdFn.prototype, Object(instance).__proto__) | |
102 } | |
103 | |
104 | |
105 function TestValueOf(type, lanes) { | |
106 var simdFn = SIMD[type]; | |
107 var instance = createInstance(type); | |
108 | |
109 assertTrue(instance === Object(instance).valueOf()) | |
110 assertTrue(instance === instance.valueOf()) | |
111 assertTrue(simdFn.prototype.valueOf.call(Object(instance)) === instance) | |
112 assertTrue(simdFn.prototype.valueOf.call(instance) === instance) | |
113 } | |
114 | |
115 | |
116 function TestGet(type, lanes) { | |
117 var simdFn = SIMD[type]; | |
118 var instance = createInstance(type); | |
119 | |
120 assertEquals(undefined, instance.a) | |
121 assertEquals(undefined, instance["a" + "b"]) | |
122 assertEquals(undefined, instance["" + "1"]) | |
123 assertEquals(undefined, instance[42]) | |
124 } | |
125 | |
126 | |
127 function TestToBoolean(type, lanes) { | |
128 var simdFn = SIMD[type]; | |
129 var instance = createInstance(type); | |
130 | |
131 assertTrue(Boolean(Object(instance))) | |
132 assertFalse(!Object(instance)) | |
133 assertTrue(Boolean(instance).valueOf()) | |
134 assertFalse(!instance) | |
135 assertTrue(!!instance) | |
136 assertTrue(instance && true) | |
137 assertFalse(!instance && false) | |
138 assertTrue(!instance || true) | |
139 assertEquals(1, instance ? 1 : 2) | |
140 assertEquals(2, !instance ? 1 : 2) | |
141 if (!instance) assertUnreachable(); | |
142 if (instance) {} else assertUnreachable(); | |
143 } | |
144 | |
145 | |
146 function TestToString(type, lanes) { | |
147 var simdFn = SIMD[type]; | |
148 var instance = createInstance(type); | |
149 | |
150 assertEquals(instance.toString(), String(instance)) | |
151 assertTrue(isValidSimdString(instance.toString(), instance, type, lanes)) | |
152 assertTrue( | |
153 isValidSimdString(Object(instance).toString(), instance, type, lanes)) | |
154 assertTrue(isValidSimdString( | |
155 simdFn.prototype.toString.call(instance), instance, type, lanes)) | |
156 } | |
157 | |
158 | |
159 function TestToNumber(type, lanes) { | |
160 var simdFn = SIMD[type]; | |
161 var instance = createInstance(type); | |
162 | |
163 assertThrows(function() { Number(Object(instance)) }, TypeError) | |
164 assertThrows(function() { +Object(instance) }, TypeError) | |
165 assertThrows(function() { Number(instance) }, TypeError) | |
166 assertThrows(function() { instance + 0 }, TypeError) | |
167 } | |
168 | |
169 | |
170 function TestCoercions(type, lanes) { | |
171 var simdFn = SIMD[type]; | |
172 var instance = createInstance(type); | |
173 // Test that setting a lane to value 'a' results in a lane with value 'b'. | |
174 function test(a, b) { | |
175 for (var i = 0; i < lanes; i++) { | |
176 var ainstance = simdFn.replaceLane(instance, i, a); | |
177 var lane_value = simdFn.extractLane(ainstance, i); | |
178 assertSame(b, lane_value); | |
179 } | |
180 } | |
181 | |
182 switch (type) { | |
183 case 'Float32x4': | |
184 test(0, 0); | |
185 test(-0, -0); | |
186 test(NaN, NaN); | |
187 test(null, 0); | |
188 test(undefined, NaN); | |
189 test("5.25", 5.25); | |
190 test(Number.MAX_VALUE, Infinity); | |
191 test(-Number.MAX_VALUE, -Infinity); | |
192 test(Number.MIN_VALUE, 0); | |
193 break; | |
194 case 'Int32x4': | |
195 test(Infinity, 0); | |
196 test(-Infinity, 0); | |
197 test(NaN, 0); | |
198 test(0, 0); | |
199 test(-0, 0); | |
200 test(Number.MIN_VALUE, 0); | |
201 test(-Number.MIN_VALUE, 0); | |
202 test(0.1, 0); | |
203 test(-0.1, 0); | |
204 test(1, 1); | |
205 test(1.1, 1); | |
206 test(-1, -1); | |
207 test(-1.6, -1); | |
208 test(2147483647, 2147483647); | |
209 test(2147483648, -2147483648); | |
210 test(2147483649, -2147483647); | |
211 test(4294967295, -1); | |
212 test(4294967296, 0); | |
213 test(4294967297, 1); | |
214 break; | |
215 case 'Uint32x4': | |
216 test(Infinity, 0); | |
217 test(-Infinity, 0); | |
218 test(NaN, 0); | |
219 test(0, 0); | |
220 test(-0, 0); | |
221 test(Number.MIN_VALUE, 0); | |
222 test(-Number.MIN_VALUE, 0); | |
223 test(0.1, 0); | |
224 test(-0.1, 0); | |
225 test(1, 1); | |
226 test(1.1, 1); | |
227 test(-1, 4294967295); | |
228 test(-1.6, 4294967295); | |
229 test(4294967295, 4294967295); | |
230 test(4294967296, 0); | |
231 test(4294967297, 1); | |
232 break; | |
233 case 'Int16x8': | |
234 test(Infinity, 0); | |
235 test(-Infinity, 0); | |
236 test(NaN, 0); | |
237 test(0, 0); | |
238 test(-0, 0); | |
239 test(Number.MIN_VALUE, 0); | |
240 test(-Number.MIN_VALUE, 0); | |
241 test(0.1, 0); | |
242 test(-0.1, 0); | |
243 test(1, 1); | |
244 test(1.1, 1); | |
245 test(-1, -1); | |
246 test(-1.6, -1); | |
247 test(32767, 32767); | |
248 test(32768, -32768); | |
249 test(32769, -32767); | |
250 test(65535, -1); | |
251 test(65536, 0); | |
252 test(65537, 1); | |
253 break; | |
254 case 'Uint16x8': | |
255 test(Infinity, 0); | |
256 test(-Infinity, 0); | |
257 test(NaN, 0); | |
258 test(0, 0); | |
259 test(-0, 0); | |
260 test(Number.MIN_VALUE, 0); | |
261 test(-Number.MIN_VALUE, 0); | |
262 test(0.1, 0); | |
263 test(-0.1, 0); | |
264 test(1, 1); | |
265 test(1.1, 1); | |
266 test(-1, 65535); | |
267 test(-1.6, 65535); | |
268 test(65535, 65535); | |
269 test(65536, 0); | |
270 test(65537, 1); | |
271 break; | |
272 case 'Int8x16': | |
273 test(Infinity, 0); | |
274 test(-Infinity, 0); | |
275 test(NaN, 0); | |
276 test(0, 0); | |
277 test(-0, 0); | |
278 test(Number.MIN_VALUE, 0); | |
279 test(-Number.MIN_VALUE, 0); | |
280 test(0.1, 0); | |
281 test(-0.1, 0); | |
282 test(1, 1); | |
283 test(1.1, 1); | |
284 test(-1, -1); | |
285 test(-1.6, -1); | |
286 test(127, 127); | |
287 test(128, -128); | |
288 test(129, -127); | |
289 test(255, -1); | |
290 test(256, 0); | |
291 test(257, 1); | |
292 break; | |
293 case 'Uint8x16': | |
294 test(Infinity, 0); | |
295 test(-Infinity, 0); | |
296 test(NaN, 0); | |
297 test(0, 0); | |
298 test(-0, 0); | |
299 test(Number.MIN_VALUE, 0); | |
300 test(-Number.MIN_VALUE, 0); | |
301 test(0.1, 0); | |
302 test(-0.1, 0); | |
303 test(1, 1); | |
304 test(1.1, 1); | |
305 test(-1, 255); | |
306 test(-1.6, 255); | |
307 test(255, 255); | |
308 test(256, 0); | |
309 test(257, 1); | |
310 break; | |
311 case 'Bool32x4': | |
312 case 'Bool16x8': | |
313 case 'Bool8x16': | |
314 test(true, true); | |
315 test(false, false); | |
316 test(0, false); | |
317 test(1, true); | |
318 test(0.1, true); | |
319 test(NaN, false); | |
320 test(null, false); | |
321 test("", false); | |
322 test("false", true); | |
323 break; | |
324 } | |
325 } | |
326 | |
327 | |
328 function TestEquality(type, lanes) { | |
329 var simdFn = SIMD[type]; | |
330 var instance = createInstance(type); | |
331 | |
332 // Every SIMD value should equal itself, and non-strictly equal its wrapper. | |
333 assertSame(instance, instance) | |
334 assertEquals(instance, instance) | |
335 assertTrue(Object.is(instance, instance)) | |
336 assertTrue(instance === instance) | |
337 assertTrue(instance == instance) | |
338 assertFalse(instance === Object(instance)) | |
339 assertFalse(Object(instance) === instance) | |
340 assertTrue(instance == Object(instance)) | |
341 assertTrue(Object(instance) == instance) | |
342 assertTrue(instance === instance.valueOf()) | |
343 assertTrue(instance.valueOf() === instance) | |
344 assertTrue(instance == instance.valueOf()) | |
345 assertTrue(instance.valueOf() == instance) | |
346 assertFalse(Object(instance) === Object(instance)) | |
347 assertEquals(Object(instance).valueOf(), Object(instance).valueOf()) | |
348 | |
349 function notEqual(other) { | |
350 assertFalse(instance === other) | |
351 assertFalse(other === instance) | |
352 assertFalse(instance == other) | |
353 assertFalse(other == instance) | |
354 } | |
355 | |
356 // SIMD values should not be equal to instances of different types. | |
357 checkTypeMatrix(type, function(other) { | |
358 assertFalse(instance === other) | |
359 assertFalse(other === instance) | |
360 assertFalse(instance == other) | |
361 assertFalse(other == instance) | |
362 }); | |
363 | |
364 // Test that f(a, b) is the same as f(SIMD(a), SIMD(b)) for equality and | |
365 // strict equality, at every lane. | |
366 function test(a, b) { | |
367 for (var i = 0; i < lanes; i++) { | |
368 var aval = simdFn.replaceLane(instance, i, a); | |
369 var bval = simdFn.replaceLane(instance, i, b); | |
370 assertSame(a == b, aval == bval); | |
371 assertSame(a === b, aval === bval); | |
372 } | |
373 } | |
374 | |
375 switch (type) { | |
376 case 'Float32x4': | |
377 test(1, 2.5); | |
378 test(1, 1); | |
379 test(0, 0); | |
380 test(-0, +0); | |
381 test(+0, -0); | |
382 test(-0, -0); | |
383 test(0, NaN); | |
384 test(NaN, NaN); | |
385 break; | |
386 case 'Int32x4': | |
387 case 'Uint32x4': | |
388 case 'Int16x8': | |
389 case 'Uint16x8': | |
390 case 'Int8x16': | |
391 case 'Uint8x16': | |
392 test(1, 2); | |
393 test(1, 1); | |
394 test(1, -1); | |
395 break; | |
396 case 'Bool32x4': | |
397 case 'Bool16x8': | |
398 case 'Bool8x16': | |
399 test(true, false); | |
400 test(false, true); | |
401 break; | |
402 } | |
403 } | |
404 | |
405 | |
406 function TestSameValue(type, lanes) { | |
407 var simdFn = SIMD[type]; | |
408 var instance = createInstance(type); | |
409 var sameValue = Object.is | |
410 var sameValueZero = function(x, y) { return %SameValueZero(x, y); } | |
411 | |
412 // SIMD values should not be the same as instances of different types. | |
413 checkTypeMatrix(type, function(other) { | |
414 assertFalse(sameValue(instance, other)); | |
415 assertFalse(sameValueZero(instance, other)); | |
416 }); | |
417 | |
418 // Test that f(a, b) is the same as f(SIMD(a), SIMD(b)) for sameValue and | |
419 // sameValueZero, at every lane. | |
420 function test(a, b) { | |
421 for (var i = 0; i < lanes; i++) { | |
422 var aval = simdFn.replaceLane(instance, i, a); | |
423 var bval = simdFn.replaceLane(instance, i, b); | |
424 assertSame(sameValue(a, b), sameValue(aval, bval)); | |
425 assertSame(sameValueZero(a, b), sameValueZero(aval, bval)); | |
426 } | |
427 } | |
428 | |
429 switch (type) { | |
430 case 'Float32x4': | |
431 test(1, 2.5); | |
432 test(1, 1); | |
433 test(0, 0); | |
434 test(-0, +0); | |
435 test(+0, -0); | |
436 test(-0, -0); | |
437 test(0, NaN); | |
438 test(NaN, NaN); | |
439 break; | |
440 case 'Int32x4': | |
441 case 'Uint32x4': | |
442 case 'Int16x8': | |
443 case 'Uint16x8': | |
444 case 'Int8x16': | |
445 case 'Uint8x16': | |
446 test(1, 2); | |
447 test(1, 1); | |
448 test(1, -1); | |
449 break; | |
450 case 'Bool32x4': | |
451 case 'Bool16x8': | |
452 case 'Bool8x16': | |
453 test(true, false); | |
454 test(false, true); | |
455 break; | |
456 } | |
457 } | |
458 | |
459 | |
460 function TestComparison(type, lanes) { | |
461 var simdFn = SIMD[type]; | |
462 var a = createInstance(type), b = createInstance(type); | |
463 | |
464 function compare(other) { | |
465 var throwFuncs = [ | |
466 function lt() { a < b; }, | |
467 function gt() { a > b; }, | |
468 function le() { a <= b; }, | |
469 function ge() { a >= b; }, | |
470 function lt_same() { a < a; }, | |
471 function gt_same() { a > a; }, | |
472 function le_same() { a <= a; }, | |
473 function ge_same() { a >= a; }, | |
474 ]; | |
475 | |
476 for (var f of throwFuncs) { | |
477 assertThrows(f, TypeError); | |
478 %OptimizeFunctionOnNextCall(f); | |
479 assertThrows(f, TypeError); | |
480 assertThrows(f, TypeError); | |
481 } | |
482 } | |
483 | |
484 // Test comparison against the same SIMD type. | |
485 compare(b); | |
486 // Test comparison against other types. | |
487 checkTypeMatrix(type, compare); | |
488 } | |
489 | |
490 | |
491 // Test SIMD value wrapping/boxing over non-builtins. | |
492 function TestCall(type, lanes) { | |
493 var simdFn = SIMD[type]; | |
494 var instance = createInstance(type); | |
495 simdFn.prototype.getThisProto = function () { | |
496 return Object.getPrototypeOf(this); | |
497 } | |
498 assertTrue(instance.getThisProto() === simdFn.prototype) | |
499 } | |
500 | |
501 | |
502 function TestAsSetKey(type, lanes, set) { | |
503 var simdFn = SIMD[type]; | |
504 var instance = createInstance(type); | |
505 | |
506 function test(set, key) { | |
507 assertFalse(set.has(key)); | |
508 assertFalse(set.delete(key)); | |
509 if (!(set instanceof WeakSet)) { | |
510 assertSame(set, set.add(key)); | |
511 assertTrue(set.has(key)); | |
512 assertTrue(set.delete(key)); | |
513 } else { | |
514 // SIMD values can't be used as keys in WeakSets. | |
515 assertThrows(function() { set.add(key) }); | |
516 } | |
517 assertFalse(set.has(key)); | |
518 assertFalse(set.delete(key)); | |
519 assertFalse(set.has(key)); | |
520 } | |
521 | |
522 test(set, instance); | |
523 } | |
524 | |
525 | |
526 function TestAsMapKey(type, lanes, map) { | |
527 var simdFn = SIMD[type]; | |
528 var instance = createInstance(type); | |
529 | |
530 function test(map, key, value) { | |
531 assertFalse(map.has(key)); | |
532 assertSame(undefined, map.get(key)); | |
533 assertFalse(map.delete(key)); | |
534 if (!(map instanceof WeakMap)) { | |
535 assertSame(map, map.set(key, value)); | |
536 assertSame(value, map.get(key)); | |
537 assertTrue(map.has(key)); | |
538 assertTrue(map.delete(key)); | |
539 } else { | |
540 // SIMD values can't be used as keys in WeakMaps. | |
541 assertThrows(function() { map.set(key, value) }); | |
542 } | |
543 assertFalse(map.has(key)); | |
544 assertSame(undefined, map.get(key)); | |
545 assertFalse(map.delete(key)); | |
546 assertFalse(map.has(key)); | |
547 assertSame(undefined, map.get(key)); | |
548 } | |
549 | |
550 test(map, instance, {}); | |
551 } | |
552 | |
553 | |
554 // Test SIMD type with Harmony reflect-apply. | |
555 function TestReflectApply(type) { | |
556 var simdFn = SIMD[type]; | |
557 var instance = createInstance(type); | |
558 | |
559 function returnThis() { return this; } | |
560 function returnThisStrict() { 'use strict'; return this; } | |
561 function noop() {} | |
562 function noopStrict() { 'use strict'; } | |
563 var R = void 0; | |
564 | |
565 assertSame(SIMD[type].prototype, | |
566 Object.getPrototypeOf( | |
567 Reflect.apply(returnThis, instance, []))); | |
568 assertSame(instance, Reflect.apply(returnThisStrict, instance, [])); | |
569 | |
570 assertThrows( | |
571 function() { 'use strict'; Reflect.apply(instance); }, TypeError); | |
572 assertThrows( | |
573 function() { Reflect.apply(instance); }, TypeError); | |
574 assertThrows( | |
575 function() { Reflect.apply(noopStrict, R, instance); }, TypeError); | |
576 assertThrows( | |
577 function() { Reflect.apply(noop, R, instance); }, TypeError); | |
578 } | |
579 | |
580 | |
581 function TestSIMDTypes() { | |
582 for (var i = 0; i < simdTypeNames.length; ++i) { | |
583 var type = simdTypeNames[i], | |
584 lanes = lanesForType(type); | |
585 TestConstructor(type, lanes); | |
586 TestType(type, lanes); | |
587 TestPrototype(type, lanes); | |
588 TestValueOf(type, lanes); | |
589 TestGet(type, lanes); | |
590 TestToBoolean(type, lanes); | |
591 TestToString(type, lanes); | |
592 TestToNumber(type, lanes); | |
593 TestCoercions(type, lanes); | |
594 TestEquality(type, lanes); | |
595 TestSameValue(type, lanes); | |
596 TestComparison(type, lanes); | |
597 TestCall(type, lanes); | |
598 TestAsSetKey(type, lanes, new Set); | |
599 TestAsSetKey(type, lanes, new WeakSet); | |
600 TestAsMapKey(type, lanes, new Map); | |
601 TestAsMapKey(type, lanes, new WeakMap); | |
602 TestReflectApply(type); | |
603 } | |
604 } | |
605 TestSIMDTypes(); | |
606 | |
607 // Tests for the global SIMD object. | |
608 function TestSIMDObject() { | |
609 assertSame(typeof SIMD, 'object'); | |
610 assertSame(SIMD.constructor, Object); | |
611 assertSame(Object.getPrototypeOf(SIMD), Object.prototype); | |
612 assertSame(SIMD + "", "[object SIMD]"); | |
613 // The SIMD object is mutable. | |
614 SIMD.foo = "foo"; | |
615 assertSame(SIMD.foo, "foo"); | |
616 delete SIMD.foo; | |
617 delete SIMD.Bool8x16; | |
618 assertSame(SIMD.Bool8x16, undefined); | |
619 } | |
620 TestSIMDObject() | |
621 | |
622 | |
623 function TestStringify(expected, input) { | |
624 assertEquals(expected, JSON.stringify(input)); | |
625 assertEquals(expected, JSON.stringify(input, (key, value) => value)); | |
626 assertEquals(JSON.stringify(input, null, "="), | |
627 JSON.stringify(input, (key, value) => value, "=")); | |
628 } | |
629 | |
630 TestStringify(undefined, SIMD.Float32x4(1, 2, 3, 4)); | |
631 TestStringify('[null]', [SIMD.Float32x4(1, 2, 3, 4)]); | |
632 TestStringify('[{}]', [Object(SIMD.Float32x4(1, 2, 3, 4))]); | |
633 var simd_wrapper = Object(SIMD.Float32x4(1, 2, 3, 4)); | |
634 TestStringify('{}', simd_wrapper); | |
635 simd_wrapper.a = 1; | |
636 TestStringify('{"a":1}', simd_wrapper); | |
OLD | NEW |