dataview-non-number-value-set.js (2750B)
1 const types = [ 2 "Int8", 3 "Int16", 4 "Int32", 5 "Uint8", 6 "Uint16", 7 "Uint32", 8 "Float16", 9 "Float32", 10 "Float64", 11 ]; 12 13 function convert(type, value) { 14 let num = Number(value); 15 switch (type) { 16 case "Int8": 17 return ((num | 0) << 24) >> 24; 18 case "Int16": 19 return ((num | 0) << 16) >> 16; 20 case "Int32": 21 return (num | 0); 22 case "Uint8": 23 return (num >>> 0) & 0xff; 24 case "Uint16": 25 return (num >>> 0) & 0xffff; 26 case "Uint32": 27 return (num >>> 0); 28 case "Uint8Clamped": { 29 if (Number.isNaN(num)) { 30 return 0; 31 } 32 let clamped = Math.max(0, Math.min(num, 255)); 33 let f = Math.floor(clamped); 34 if (clamped < f + 0.5) { 35 return f; 36 } 37 if (clamped > f + 0.5) { 38 return f + 1; 39 } 40 return f + (f & 1); 41 } 42 case "Float16": 43 return Math.f16round(num); 44 case "Float32": 45 return Math.fround(num); 46 case "Float64": 47 return num; 48 } 49 throw new Error(); 50 } 51 52 53 function runTest(type, initial, values) { 54 let expected = values.map(v => convert(type, v)); 55 assertEq( 56 expected.some(e => Object.is(e, initial)), 57 false, 58 "initial must be different from the expected values" 59 ); 60 61 // Create a fresh function to ensure ICs are specific to a single DataView function. 62 let test = Function("initial, values, expected", ` 63 let ab = new ArrayBuffer(16); 64 let dv = new DataView(ab); 65 for (let i = 0; i < 200; ++i) { 66 dv.set${type}(0, initial); 67 dv.set${type}(0, values[i % values.length]); 68 assertEq(dv.get${type}(0), expected[i % expected.length]); 69 } 70 `); 71 test(initial, values, expected); 72 } 73 74 const tests = [ 75 // |null| is coerced to zero. 76 { 77 initial: 1, 78 values: [null], 79 }, 80 81 // |undefined| is coerced to zero or NaN. 82 { 83 initial: 1, 84 values: [undefined], 85 }, 86 87 // |false| is coerced to zero and |true| is coerced to one. 88 { 89 initial: 2, 90 values: [false, true], 91 }, 92 93 // Strings without a fractional part. 94 { 95 initial: 42, 96 values: [ 97 "0", "1", "10", "111", "128", "256", "0x7fffffff", "0xffffffff", 98 ], 99 }, 100 101 // Strings without a fractional part, but a leading minus sign. 102 { 103 initial: 42, 104 values: [ 105 "-0", "-1", "-10", "-111", "-128", "-256", "-2147483647", "-4294967295", 106 ], 107 }, 108 109 // Strings with a fractional number part. 110 { 111 initial: 42, 112 values: [ 113 "0.1", "1.2", "10.8", "111.9", 114 "-0.1", "-1.2", "-10.8", "-111.9", 115 ], 116 }, 117 118 // Special values and strings not parseable as a number. 119 { 120 initial: 42, 121 values: ["Infinity", "-Infinity", "NaN", "foobar"], 122 }, 123 ]; 124 125 for (let type of types) { 126 for (let {initial, values} of tests) { 127 runTest(type, initial, values); 128 } 129 }