Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 // A test to compare the results of the fixnum library with the Dart VM | |
| 6 | |
| 7 #library('int64vmtest'); | |
| 8 #source('../../../lib/fixnum/intx.dart'); | |
| 9 #source('../../../lib/fixnum/int32.dart'); | |
| 10 #source('../../../lib/fixnum/int64.dart'); | |
| 11 | |
| 12 void main() { | |
| 13 print("int64 vm test"); | |
|
Mads Ager (google)
2012/06/13 08:43:09
Remove?
Dan Rice
2012/06/14 14:38:41
Fixed.
On 2012/06/13 08:43:09, Mads Ager wrote:
| |
| 14 | |
| 15 int64VMTest test = new int64VMTest(); | |
| 16 test.doTestBinary(new BinaryOp("&", (a, b) => a & b)); | |
| 17 test.doTestBinary(new BinaryOp("|", (a, b) => a | b)); | |
| 18 test.doTestBinary(new BinaryOp("^", (a, b) => a ^ b)); | |
| 19 test.doTestBinary(new BinaryOp("+", (a, b) => a + b)); | |
| 20 test.doTestBinary(new BinaryOp("-", (a, b) => a - b)); | |
| 21 test.doTestBinary(new BinaryOp("*", (a, b) => a * b)); | |
| 22 test.doTestUnary(new UnaryOp("-", (a) => -a)); | |
| 23 test.doTestUnary(new UnaryOp("~", (a) => ~a)); | |
| 24 test.doTestShift(new ShiftOp("<<", (a, n) => a << (n & 63))); | |
| 25 test.doTestShift(new ShiftOp(">>", (a, n) => a >> (n & 63))); | |
| 26 test.doTestBoolean(new BooleanOp("compareTo", (a, b) => a.compareTo(b))); | |
| 27 test.doTestBoolean(new BooleanOp("==", (a, b) => a == b)); | |
| 28 test.doTestBoolean(new BooleanOp("!=", (a, b) => a != b)); | |
| 29 test.doTestBoolean(new BooleanOp("<", (a, b) => a < b)); | |
| 30 test.doTestBoolean(new BooleanOp("<=", (a, b) => a <= b)); | |
| 31 test.doTestBoolean(new BooleanOp(">", (a, b) => a > b)); | |
| 32 test.doTestBoolean(new BooleanOp(">=", (a, b) => a >= b)); | |
| 33 test.doTestBinary(new BinaryOp("%", (a, b) => a % b)); | |
| 34 test.doTestBinary(new BinaryOp("~/", (a, b) => a ~/ b)); | |
| 35 test.doTestBinary(new BinaryOp("remainder", (a, b) => a.remainder(b))); | |
| 36 | |
| 37 /* | |
| 38 testBase64(); | |
|
Mads Ager (google)
2012/06/13 08:43:09
Code in comments. Remove for now. It would make se
Dan Rice
2012/06/14 14:38:41
Removed.
On 2012/06/13 08:43:09, Mads Ager wrote:
| |
| 39 testCompare(); | |
| 40 testGetAsIntArray(); | |
| 41 testNumberOfLeadingZeros(); | |
| 42 testRoundTrip(); | |
| 43 testShru(); | |
| 44 */ | |
| 45 } | |
| 46 | |
| 47 final int DISCARD = 0; | |
| 48 | |
| 49 int64 _randomInt64() { | |
| 50 int i = 0; | |
| 51 for (int b = 0; b < 64; b++) { | |
| 52 double rand = Math.random(); | |
| 53 for (int j = 0; j < DISCARD; j++) { | |
| 54 rand = Math.random(); | |
| 55 } | |
| 56 i = (i << 1) | ((rand > 0.5) ? 1 : 0); | |
| 57 } | |
| 58 return new int64.fromInt(i); | |
| 59 } | |
| 60 | |
| 61 int _randomInt(int n) { | |
| 62 double rand = Math.random(); | |
| 63 for (int i = 0; i < DISCARD; i++) { | |
| 64 rand = Math.random(); | |
| 65 } | |
| 66 return (rand * n).floor().toInt(); | |
| 67 } | |
| 68 | |
| 69 class Op { | |
| 70 String name; | |
| 71 Function op; | |
| 72 | |
| 73 Op(String this.name, Function this.op); | |
| 74 | |
| 75 // Truncate x to a value in the range [-2^63, 2^63 - 1] | |
| 76 int trunc64(int x) { | |
| 77 int trunc = x & 0xffffffffffffffff; | |
| 78 if ((trunc & 0x8000000000000000) != 0) { | |
| 79 trunc -= 18446744073709551616; // 2^64 | |
| 80 } | |
| 81 return trunc; | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 class UnaryOp extends Op { | |
| 86 UnaryOp(String name, Function op) : super(name, op); | |
| 87 int ref(int val) => trunc64(op(val)); | |
| 88 int64 test(int64 val) => op(val); | |
| 89 } | |
| 90 | |
| 91 class BinaryOp extends Op { | |
| 92 BinaryOp(String name, Function op) : super(name, op); | |
| 93 int ref(int val0, int val1) => trunc64(op(val0, val1)); | |
| 94 int64 test(int64 val0, int64 val1) => op(val0, val1); | |
| 95 } | |
| 96 | |
| 97 class BooleanOp extends Op { | |
| 98 BooleanOp(String name, Function op) : super(name, op); | |
| 99 bool ref(int val0, int val1) => op(val0, val1); | |
| 100 bool test(int64 val0, int64 val1) => op(val0, val1); | |
| 101 } | |
| 102 | |
| 103 class ShiftOp extends Op { | |
| 104 ShiftOp(String name, Function op) : super(name, op); | |
| 105 int ref(int val0, int shift) => trunc64(op(val0, shift)); | |
| 106 int64 test(int64 val0, int shift) => op(val0, shift); | |
| 107 } | |
| 108 | |
| 109 class int64VMTest { | |
| 110 static final int BASE_VALUES = 32; | |
| 111 static final int RANDOM_TESTS = 32; | |
| 112 List<int64> TEST_VALUES; | |
| 113 | |
| 114 int64VMTest() { | |
| 115 Set<int64> testSet = new Set<int64>(); | |
| 116 for (int i = 0; i < BASE_VALUES; i++) { | |
| 117 testSet.add(new int64.fromInt(i)); | |
| 118 testSet.add(new int64.fromInt(-i)); | |
| 119 | |
| 120 testSet.add(int64.MIN_VALUE + i); | |
| 121 testSet.add(int64.MAX_VALUE - i); | |
| 122 | |
| 123 testSet.add(new int64.fromInt(i << int64._BITS ~/ 2)); | |
| 124 testSet.add(new int64.fromInt(i << int64._BITS)); | |
| 125 testSet.add(new int64.fromInt(i << (3 * int64._BITS) ~/ 2)); | |
| 126 testSet.add(new int64.fromInt(i << 2 * int64._BITS)); | |
| 127 testSet.add(new int64.fromInt(i << (5 * int64._BITS) ~/ 2)); | |
| 128 } | |
| 129 | |
| 130 int64 one = new int64.fromInt(1); | |
| 131 int64 three = new int64.fromInt(3); | |
| 132 int64 ones = int64.parseHex("1111111111111111"); | |
| 133 int64 tens = int64.parseHex("1010101010101010"); | |
| 134 int64 oh_ones = int64.parseHex("0101010101010101"); | |
| 135 int64 digits = int64.parseHex("123456789ABCDEFF"); | |
| 136 for (int i = 0; i < 16; i++) { | |
| 137 testSet.add(ones * i); | |
| 138 testSet.add(~(ones * i)); | |
| 139 testSet.add(-(ones * i)); | |
| 140 testSet.add(tens * i); | |
| 141 testSet.add(~(tens * i)); | |
| 142 testSet.add(-(tens * i)); | |
| 143 testSet.add(oh_ones * i); | |
| 144 testSet.add(~(oh_ones * i)); | |
| 145 testSet.add(-(oh_ones * i)); | |
| 146 testSet.add(digits * i); | |
| 147 testSet.add(~(digits * i)); | |
| 148 testSet.add(-(digits * i)); | |
| 149 } | |
| 150 | |
| 151 for (int i = 0; i < 64; i += 4) { | |
| 152 testSet.add(one << i); | |
| 153 testSet.add(~(one << i)); | |
| 154 testSet.add(digits >> i); | |
| 155 testSet.add(-(digits >> i)); | |
| 156 | |
| 157 // Powers of two and nearby numbers | |
| 158 testSet.add(one << i); | |
| 159 for (int j = 1; j <= 16; j++) { | |
| 160 testSet.add((one << i) + j); | |
| 161 testSet.add(-((one << i) + j)); | |
| 162 testSet.add(~((one << i) + j)); | |
| 163 testSet.add((one << i) - j); | |
| 164 testSet.add(-((one << i) - j)); | |
| 165 testSet.add(~((one << i) - j)); | |
| 166 testSet.add((three << i) + j); | |
| 167 testSet.add(-((three << i) + j)); | |
| 168 testSet.add(~((three << i) + j)); | |
| 169 testSet.add((three << i) - j); | |
| 170 testSet.add(-((three << i) - j)); | |
| 171 testSet.add(~((three << i) - j)); | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 for (int a = 0; a < 19; a++) { | |
| 176 // Math.pow(10, a) | |
| 177 int pow = 1; | |
| 178 for (int j = 0; j < a; j++) { | |
| 179 pow *= 10; | |
| 180 } | |
| 181 testSet.add(new int64.fromInt(pow)); | |
| 182 } | |
| 183 | |
| 184 TEST_VALUES = new List<int64>(testSet.length); | |
| 185 int index = 0; | |
| 186 for (int64 val in testSet) { | |
| 187 TEST_VALUES[index++] = val; | |
| 188 } | |
| 189 | |
| 190 print("VALUES.length = $index"); | |
| 191 } | |
| 192 | |
| 193 void _doTestUnary(UnaryOp op, int64 val) { | |
| 194 int ref = op.ref(val.toInt()); | |
| 195 int64 result64 = op.test(val); | |
| 196 int result = result64.toInt(); | |
| 197 if (ref != result) { | |
| 198 Expect.fail("${op.name}: val = $val"); | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 void doTestUnary(UnaryOp op) { | |
| 203 print("Testing operator ${op.name}"); | |
| 204 for (int i = 0; i < TEST_VALUES.length; i++) { | |
| 205 _doTestUnary(op, TEST_VALUES[i]); | |
| 206 } | |
| 207 for (int i = 0; i < RANDOM_TESTS; i++) { | |
| 208 int64 randomLong = _randomInt64(); | |
| 209 _doTestUnary(op, randomLong); | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 void _doTestBinary(BinaryOp op, int64 val0, int64 val1) { | |
| 214 // print("Test val0 = $val0, val1 = $val1"); | |
| 215 var refException = null; | |
| 216 int ref = -1; | |
| 217 try { | |
| 218 ref = op.ref(val0.toInt(), val1.toInt()); | |
| 219 } catch (Exception e) { | |
| 220 refException = e; | |
| 221 } | |
| 222 var testException = null; | |
| 223 int result = -2; | |
| 224 int64 result64; | |
| 225 try { | |
| 226 int64 val0_save = new int64._copy(val0); | |
| 227 int64 val1_save = new int64._copy(val1); | |
| 228 result64 = op.test(val0, val1); | |
| 229 result = result64.toInt(); | |
| 230 if (val0 != val0_save) { | |
| 231 print( | |
| 232 "Test altered first argument val0 = $val0, val0_save = $val0_save"); | |
| 233 } | |
| 234 if (val1 != val1_save) { | |
| 235 print("Test altered second argument"); | |
| 236 } | |
| 237 } catch (Exception e) { | |
| 238 testException = e; | |
| 239 } | |
| 240 if (testException is IntegerDivisionByZeroException && | |
| 241 refException is IntegerDivisionByZeroException) { | |
| 242 } else if (testException != null || refException != null) { | |
| 243 Expect.fail("${op.name}: val0 = $val0, val1 = $val1, " | |
| 244 "testException = $testException, refException = $refException"); | |
| 245 return; | |
| 246 } else if (ref != result) { | |
| 247 if ("%" == op.name && ref < 0) { | |
| 248 // print("Dart VM bug: ${op.name}: val0 = $val0, val1 = $val1, " | |
| 249 // "ref = $ref, result64 = $result64, result = $result"); | |
| 250 } else { | |
| 251 Expect.fail("${op.name}: val0 = $val0, val1 = $val1, " | |
| 252 "ref = $ref, result64 = $result64, result = $result"); | |
| 253 } | |
| 254 } | |
| 255 } | |
| 256 | |
| 257 void doTestBinary(BinaryOp op) { | |
| 258 print("Testing operator ${op.name}"); | |
| 259 for (int i = 0; i < TEST_VALUES.length; i++) { | |
| 260 int64 randomLong = _randomInt64(); | |
| 261 _doTestBinary(op, TEST_VALUES[i], randomLong); | |
| 262 _doTestBinary(op, randomLong, TEST_VALUES[i]); | |
| 263 for (int j = 0; j < TEST_VALUES.length; j++) { | |
| 264 _doTestBinary(op, TEST_VALUES[i], TEST_VALUES[j]); | |
| 265 } | |
| 266 } | |
| 267 for (int i = 0; i < RANDOM_TESTS; i++) { | |
| 268 int64 longVal0 = _randomInt64(); | |
| 269 int64 longVal1 = _randomInt64(); | |
| 270 if (_randomInt(20) == 0) { | |
| 271 if (_randomInt(2) == 0) { | |
| 272 longVal1 = longVal0; | |
| 273 } else { | |
| 274 longVal1 = -longVal0; | |
| 275 } | |
| 276 } | |
| 277 _doTestBinary(op, longVal0, longVal1); | |
| 278 } | |
| 279 } | |
| 280 | |
| 281 void _doTestBoolean(BooleanOp op, int64 val0, int64 val1) { | |
| 282 bool ref = op.ref(val0.toInt(), val1.toInt()); | |
| 283 bool result = op.test(val0, val1); | |
| 284 if (ref != result) { | |
| 285 Expect.fail("${op.name}: val0 = $val0, val1 = $val1"); | |
| 286 } | |
| 287 } | |
| 288 | |
| 289 void doTestBoolean(BooleanOp op) { | |
| 290 print("Testing operator ${op.name}"); | |
| 291 for (int i = 0; i < TEST_VALUES.length; i++) { | |
| 292 int64 randomLong = _randomInt64(); | |
| 293 _doTestBoolean(op, TEST_VALUES[i], randomLong); | |
| 294 _doTestBoolean(op, randomLong, TEST_VALUES[i]); | |
| 295 for (int j = 0; j < TEST_VALUES.length; j++) { | |
| 296 _doTestBoolean(op, TEST_VALUES[i], TEST_VALUES[j]); | |
| 297 } | |
| 298 } | |
| 299 for (int i = 0; i < RANDOM_TESTS; i++) { | |
| 300 int64 longVal0 = _randomInt64(); | |
| 301 int64 longVal1 = _randomInt64(); | |
| 302 if (_randomInt(20) == 0) { | |
| 303 if (_randomInt(2) == 0) { | |
| 304 longVal1 = longVal0; | |
| 305 } else { | |
| 306 longVal1 = -longVal0; | |
| 307 } | |
| 308 } | |
| 309 _doTestBoolean(op, longVal0, longVal1); | |
| 310 } | |
| 311 } | |
| 312 | |
| 313 void _doTestShift(ShiftOp op, int64 val, int shift) { | |
| 314 int ref = op.ref(val.toInt(), shift); | |
| 315 int64 result64 = op.test(val, shift); | |
| 316 int result = result64.toInt(); | |
| 317 if (ref != result) { | |
| 318 Expect.fail("${op.name}: val = $val, shift = $shift"); | |
| 319 } | |
| 320 } | |
| 321 | |
| 322 void doTestShift(ShiftOp op) { | |
| 323 print("Testing operator ${op.name}"); | |
| 324 for (int i = 0; i < TEST_VALUES.length; i++) { | |
| 325 for (int shift = -64; shift <= 64; shift++) { | |
| 326 _doTestShift(op, TEST_VALUES[i], shift); | |
| 327 } | |
| 328 } | |
| 329 for (int i = 0; i < RANDOM_TESTS; i++) { | |
| 330 int64 randomLong = _randomInt64(); | |
| 331 for (int shift = -64; shift <= 64; shift++) { | |
| 332 _doTestShift(op, randomLong, shift); | |
| 333 } | |
| 334 } | |
| 335 } | |
| 336 } | |
| OLD | NEW |