| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // A test to compare the results of the fixnum library with the Dart VM | 5 // A test to compare the results of the fixnum library with the Dart VM |
| 6 | 6 |
| 7 library int64vmtest; | 7 library int64vmtest; |
| 8 | 8 |
| 9 import "package:expect/expect.dart"; | |
| 10 import 'dart:math' as math; | 9 import 'dart:math' as math; |
| 11 | 10 import 'package:fixnum/fixnum.dart'; |
| 12 part 'package:fixnum/src/int32.dart'; | 11 import "package:unittest/unittest.dart"; |
| 13 part 'package:fixnum/src/int64.dart'; | |
| 14 part 'package:fixnum/src/intx.dart'; | |
| 15 | |
| 16 final random = new math.Random(); | |
| 17 | 12 |
| 18 void main() { | 13 void main() { |
| 19 int64VMTest test = new int64VMTest(); | 14 int64VMTest test = new int64VMTest(); |
| 20 test.doTestBinary(new BinaryOp("&", (a, b) => a & b)); | 15 test.doTestBinary(new BinaryOp("&", (a, b) => a & b)); |
| 21 test.doTestBinary(new BinaryOp("|", (a, b) => a | b)); | 16 test.doTestBinary(new BinaryOp("|", (a, b) => a | b)); |
| 22 test.doTestBinary(new BinaryOp("^", (a, b) => a ^ b)); | 17 test.doTestBinary(new BinaryOp("^", (a, b) => a ^ b)); |
| 23 test.doTestBinary(new BinaryOp("+", (a, b) => a + b)); | 18 test.doTestBinary(new BinaryOp("+", (a, b) => a + b)); |
| 24 test.doTestBinary(new BinaryOp("-", (a, b) => a - b)); | 19 test.doTestBinary(new BinaryOp("-", (a, b) => a - b)); |
| 25 test.doTestBinary(new BinaryOp("*", (a, b) => a * b)); | 20 test.doTestBinary(new BinaryOp("*", (a, b) => a * b)); |
| 26 test.doTestUnary(new UnaryOp("-", (a) => -a)); | 21 test.doTestUnary(new UnaryOp("-", (a) => -a)); |
| 27 test.doTestUnary(new UnaryOp("~", (a) => ~a)); | 22 test.doTestUnary(new UnaryOp("~", (a) => ~a)); |
| 28 test.doTestShift(new ShiftOp("<<", (a, n) => a << (n & 63))); | 23 test.doTestShift(new ShiftOp("<<", (a, n) => a << (n & 63))); |
| 29 test.doTestShift(new ShiftOp(">>", (a, n) => a >> (n & 63))); | 24 test.doTestShift(new ShiftOp(">>", (a, n) => a >> (n & 63))); |
| 30 test.doTestBoolean(new BooleanOp("compareTo", (a, b) => a.compareTo(b))); | 25 test.doTestComparison(new ComparisonOp("compareTo", (a, b) => a.compareTo(b)))
; |
| 31 test.doTestBoolean(new BooleanOp("==", (a, b) => a == b)); | 26 test.doTestBoolean(new BooleanOp("==", (a, b) => a == b)); |
| 32 test.doTestBoolean(new BooleanOp("!=", (a, b) => a != b)); | 27 test.doTestBoolean(new BooleanOp("!=", (a, b) => a != b)); |
| 33 test.doTestBoolean(new BooleanOp("<", (a, b) => a < b)); | 28 test.doTestBoolean(new BooleanOp("<", (a, b) => a < b)); |
| 34 test.doTestBoolean(new BooleanOp("<=", (a, b) => a <= b)); | 29 test.doTestBoolean(new BooleanOp("<=", (a, b) => a <= b)); |
| 35 test.doTestBoolean(new BooleanOp(">", (a, b) => a > b)); | 30 test.doTestBoolean(new BooleanOp(">", (a, b) => a > b)); |
| 36 test.doTestBoolean(new BooleanOp(">=", (a, b) => a >= b)); | 31 test.doTestBoolean(new BooleanOp(">=", (a, b) => a >= b)); |
| 37 test.doTestBinary(new BinaryOp("%", (a, b) => a % b)); | 32 test.doTestBinary(new BinaryOp("%", (a, b) => a % b)); |
| 38 test.doTestBinary(new BinaryOp("~/", (a, b) => a ~/ b)); | 33 test.doTestBinary(new BinaryOp("~/", (a, b) => a ~/ b)); |
| 39 test.doTestBinary(new BinaryOp("remainder", (a, b) => a.remainder(b))); | 34 test.doTestBinary(new BinaryOp("remainder", (a, b) => a.remainder(b))); |
| 40 } | 35 } |
| 41 | 36 |
| 37 final random = new math.Random(); |
| 42 const int DISCARD = 0; | 38 const int DISCARD = 0; |
| 43 | 39 |
| 44 int64 _randomInt64() { | 40 int64 _randomInt64() { |
| 45 int i = 0; | 41 int i = 0; |
| 46 for (int b = 0; b < 64; b++) { | 42 for (int b = 0; b < 64; b++) { |
| 47 double rand = random.nextDouble(); | 43 double rand = random.nextDouble(); |
| 48 for (int j = 0; j < DISCARD; j++) { | 44 for (int j = 0; j < DISCARD; j++) { |
| 49 rand = random.nextDouble(); | 45 rand = random.nextDouble(); |
| 50 } | 46 } |
| 51 i = (i << 1) | ((rand > 0.5) ? 1 : 0); | 47 i = (i << 1) | ((rand > 0.5) ? 1 : 0); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 bool ref(int val0, int val1) => op(val0, val1); | 90 bool ref(int val0, int val1) => op(val0, val1); |
| 95 bool test(int64 val0, int64 val1) => op(val0, val1); | 91 bool test(int64 val0, int64 val1) => op(val0, val1); |
| 96 } | 92 } |
| 97 | 93 |
| 98 class ShiftOp extends Op { | 94 class ShiftOp extends Op { |
| 99 ShiftOp(String name, Function op) : super(name, op); | 95 ShiftOp(String name, Function op) : super(name, op); |
| 100 int ref(int val0, int shift) => trunc64(op(val0, shift)); | 96 int ref(int val0, int shift) => trunc64(op(val0, shift)); |
| 101 int64 test(int64 val0, int shift) => op(val0, shift); | 97 int64 test(int64 val0, int shift) => op(val0, shift); |
| 102 } | 98 } |
| 103 | 99 |
| 100 class ComparisonOp extends Op { |
| 101 ComparisonOp(String name, Function op) : super(name, op); |
| 102 int ref(int val0, int val1) => trunc64(op(val0, val1)); |
| 103 int test(int64 val0, int64 val1) => op(val0, val1); |
| 104 } |
| 105 |
| 104 class int64VMTest { | 106 class int64VMTest { |
| 105 static const int BASE_VALUES = 32; | 107 static const int BASE_VALUES = 32; |
| 106 static const int RANDOM_TESTS = 32; | 108 static const int RANDOM_TESTS = 32; |
| 107 List<int64> TEST_VALUES; | 109 List<int64> TEST_VALUES; |
| 108 | 110 |
| 109 int64VMTest() { | 111 int64VMTest() { |
| 110 Set<int64> testSet = new Set<int64>(); | 112 Set<int64> testSet = new Set<int64>(); |
| 111 for (int i = 0; i < BASE_VALUES; i++) { | 113 for (int i = 0; i < 64; i++) { |
| 112 testSet.add(new int64.fromInt(i)); | 114 testSet.add(new int64.fromInt(i)); |
| 113 testSet.add(new int64.fromInt(-i)); | 115 testSet.add(new int64.fromInt(-i)); |
| 114 | 116 |
| 115 testSet.add(int64.MIN_VALUE + i); | 117 testSet.add(int64.MIN_VALUE + i); |
| 116 testSet.add(int64.MAX_VALUE - i); | 118 testSet.add(int64.MAX_VALUE - i); |
| 117 | 119 |
| 118 testSet.add(new int64.fromInt(i << int64._BITS ~/ 2)); | 120 testSet.add(new int64.fromInt(0xf << i)); |
| 119 testSet.add(new int64.fromInt(i << int64._BITS)); | |
| 120 testSet.add(new int64.fromInt(i << (3 * int64._BITS) ~/ 2)); | |
| 121 testSet.add(new int64.fromInt(i << 2 * int64._BITS)); | |
| 122 testSet.add(new int64.fromInt(i << (5 * int64._BITS) ~/ 2)); | |
| 123 } | 121 } |
| 124 | 122 |
| 125 int64 one = new int64.fromInt(1); | 123 int64 one = new int64.fromInt(1); |
| 126 int64 three = new int64.fromInt(3); | 124 int64 three = new int64.fromInt(3); |
| 127 int64 ones = int64.parseHex("1111111111111111"); | 125 int64 ones = int64.parseHex("1111111111111111"); |
| 128 int64 tens = int64.parseHex("1010101010101010"); | 126 int64 tens = int64.parseHex("1010101010101010"); |
| 129 int64 oh_ones = int64.parseHex("0101010101010101"); | 127 int64 oh_ones = int64.parseHex("0101010101010101"); |
| 130 int64 digits = int64.parseHex("123456789ABCDEFF"); | 128 int64 digits = int64.parseHex("123456789ABCDEFF"); |
| 131 for (int i = 0; i < 16; i++) { | 129 for (int i = 0; i < 16; i++) { |
| 132 testSet.add(ones * i); | 130 testSet.add(ones * i); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 TEST_VALUES[index++] = val; | 180 TEST_VALUES[index++] = val; |
| 183 } | 181 } |
| 184 | 182 |
| 185 print("VALUES.length = $index"); | 183 print("VALUES.length = $index"); |
| 186 } | 184 } |
| 187 | 185 |
| 188 void _doTestUnary(UnaryOp op, int64 val) { | 186 void _doTestUnary(UnaryOp op, int64 val) { |
| 189 int ref = op.ref(val.toInt()); | 187 int ref = op.ref(val.toInt()); |
| 190 int64 result64 = op.test(val); | 188 int64 result64 = op.test(val); |
| 191 int result = result64.toInt(); | 189 int result = result64.toInt(); |
| 192 if (ref != result) { | 190 expect(ref == result, true, reason: "${op.name}: val = $val"); |
| 193 Expect.fail("${op.name}: val = $val"); | |
| 194 } | |
| 195 } | 191 } |
| 196 | 192 |
| 197 void doTestUnary(UnaryOp op) { | 193 void doTestUnary(UnaryOp op) { |
| 198 print("Testing operator ${op.name}"); | 194 print("Testing operator ${op.name}"); |
| 199 for (int i = 0; i < TEST_VALUES.length; i++) { | 195 for (int i = 0; i < TEST_VALUES.length; i++) { |
| 200 _doTestUnary(op, TEST_VALUES[i]); | 196 _doTestUnary(op, TEST_VALUES[i]); |
| 201 } | 197 } |
| 202 for (int i = 0; i < RANDOM_TESTS; i++) { | 198 for (int i = 0; i < RANDOM_TESTS; i++) { |
| 203 int64 randomLong = _randomInt64(); | 199 int64 randomLong = _randomInt64(); |
| 204 _doTestUnary(op, randomLong); | 200 _doTestUnary(op, randomLong); |
| 205 } | 201 } |
| 206 } | 202 } |
| 207 | 203 |
| 208 void _doTestBinary(BinaryOp op, int64 val0, int64 val1) { | 204 void _doTestBinary(BinaryOp op, int64 val0, int64 val1) { |
| 209 // print("Test val0 = $val0, val1 = $val1"); | |
| 210 var refException = null; | 205 var refException = null; |
| 211 int ref = -1; | 206 int ref = -1; |
| 212 try { | 207 try { |
| 213 ref = op.ref(val0.toInt(), val1.toInt()); | 208 ref = op.ref(val0.toInt(), val1.toInt()); |
| 214 } on Exception catch (e) { | 209 } on Exception catch (e) { |
| 215 refException = e; | 210 refException = e; |
| 216 } | 211 } |
| 217 var testException = null; | 212 var testException = null; |
| 218 int result = -2; | 213 int result = -2; |
| 219 int64 result64; | 214 int64 result64; |
| 220 try { | 215 try { |
| 221 int64 val0_save = new int64._copy(val0); | 216 int val0_save = val0.toInt(); |
| 222 int64 val1_save = new int64._copy(val1); | 217 int val1_save = val1.toInt(); |
| 223 result64 = op.test(val0, val1); | 218 result64 = op.test(val0, val1); |
| 224 result = result64.toInt(); | 219 result = result64.toInt(); |
| 225 if (val0 != val0_save) { | 220 if (val0.toInt() != val0_save) { |
| 226 print( | 221 fail("Test altered val0 = $val0, val0_save = $val0_save"); |
| 227 "Test altered first argument val0 = $val0, val0_save = $val0_save"); | |
| 228 } | 222 } |
| 229 if (val1 != val1_save) { | 223 if (val1.toInt() != val1_save) { |
| 230 print("Test altered second argument"); | 224 fail("Test altered val1 = $val1, val1_save = $val1_save"); |
| 231 } | 225 } |
| 232 } on Exception catch (e) { | 226 } on Exception catch (e) { |
| 233 testException = e; | 227 testException = e; |
| 234 } | 228 } |
| 235 if (testException is IntegerDivisionByZeroException && | 229 if (testException is IntegerDivisionByZeroException && |
| 236 refException is IntegerDivisionByZeroException) { | 230 refException is IntegerDivisionByZeroException) { |
| 237 } else if (testException != null || refException != null) { | 231 } else if (testException != null || refException != null) { |
| 238 Expect.fail("${op.name}: val0 = $val0, val1 = $val1, " | 232 fail("${op.name}: val0 = $val0, val1 = $val1, " |
| 239 "testException = $testException, refException = $refException"); | 233 "testException = $testException, refException = $refException"); |
| 240 return; | 234 return; |
| 241 } else if (ref != result) { | 235 } else if (ref != result) { |
| 242 if ("%" == op.name && ref < 0) { | 236 if ("%" == op.name && ref < 0) { |
| 243 // print("Dart VM bug: ${op.name}: val0 = $val0, val1 = $val1, " | 237 fail("Dart VM bug: ${op.name}: val0 = $val0, val1 = $val1, " |
| 244 // "ref = $ref, result64 = $result64, result = $result"); | 238 "ref = $ref, result64 = $result64, result = $result"); |
| 245 } else { | 239 } else { |
| 246 Expect.fail("${op.name}: val0 = $val0, val1 = $val1, " | 240 fail("${op.name}: val0 = $val0, val1 = $val1, " |
| 247 "ref = $ref, result64 = $result64, result = $result"); | 241 "ref = $ref, result64 = $result64, result = $result"); |
| 248 } | 242 } |
| 249 } | 243 } |
| 250 } | 244 } |
| 251 | 245 |
| 252 void doTestBinary(BinaryOp op) { | 246 void doTestBinary(BinaryOp op) { |
| 253 print("Testing operator ${op.name}"); | 247 print("Testing operator ${op.name}"); |
| 254 for (int i = 0; i < TEST_VALUES.length; i++) { | 248 for (int i = 0; i < TEST_VALUES.length; i++) { |
| 255 int64 randomLong = _randomInt64(); | 249 int64 randomLong = _randomInt64(); |
| 256 _doTestBinary(op, TEST_VALUES[i], randomLong); | 250 _doTestBinary(op, TEST_VALUES[i], randomLong); |
| 257 _doTestBinary(op, randomLong, TEST_VALUES[i]); | 251 _doTestBinary(op, randomLong, TEST_VALUES[i]); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 269 longVal1 = -longVal0; | 263 longVal1 = -longVal0; |
| 270 } | 264 } |
| 271 } | 265 } |
| 272 _doTestBinary(op, longVal0, longVal1); | 266 _doTestBinary(op, longVal0, longVal1); |
| 273 } | 267 } |
| 274 } | 268 } |
| 275 | 269 |
| 276 void _doTestBoolean(BooleanOp op, int64 val0, int64 val1) { | 270 void _doTestBoolean(BooleanOp op, int64 val0, int64 val1) { |
| 277 bool ref = op.ref(val0.toInt(), val1.toInt()); | 271 bool ref = op.ref(val0.toInt(), val1.toInt()); |
| 278 bool result = op.test(val0, val1); | 272 bool result = op.test(val0, val1); |
| 279 if (ref != result) { | 273 expect(ref == result, true, |
| 280 Expect.fail("${op.name}: val0 = $val0, val1 = $val1"); | 274 reason: "${op.name}: val0 = $val0, val1 = $val1"); |
| 281 } | |
| 282 } | 275 } |
| 283 | 276 |
| 284 void doTestBoolean(BooleanOp op) { | 277 void doTestBoolean(BooleanOp op) { |
| 285 print("Testing operator ${op.name}"); | 278 print("Testing operator ${op.name}"); |
| 286 for (int i = 0; i < TEST_VALUES.length; i++) { | 279 for (int i = 0; i < TEST_VALUES.length; i++) { |
| 287 int64 randomLong = _randomInt64(); | 280 int64 randomLong = _randomInt64(); |
| 288 _doTestBoolean(op, TEST_VALUES[i], randomLong); | 281 _doTestBoolean(op, TEST_VALUES[i], randomLong); |
| 289 _doTestBoolean(op, randomLong, TEST_VALUES[i]); | 282 _doTestBoolean(op, randomLong, TEST_VALUES[i]); |
| 290 for (int j = 0; j < TEST_VALUES.length; j++) { | 283 for (int j = 0; j < TEST_VALUES.length; j++) { |
| 291 _doTestBoolean(op, TEST_VALUES[i], TEST_VALUES[j]); | 284 _doTestBoolean(op, TEST_VALUES[i], TEST_VALUES[j]); |
| 292 } | 285 } |
| 293 } | 286 } |
| 294 for (int i = 0; i < RANDOM_TESTS; i++) { | 287 for (int i = 0; i < RANDOM_TESTS; i++) { |
| 295 int64 longVal0 = _randomInt64(); | 288 int64 longVal0 = _randomInt64(); |
| 296 int64 longVal1 = _randomInt64(); | 289 int64 longVal1 = _randomInt64(); |
| 297 if (_randomInt(20) == 0) { | 290 if (_randomInt(20) == 0) { |
| 298 if (_randomInt(2) == 0) { | 291 if (_randomInt(2) == 0) { |
| 299 longVal1 = longVal0; | 292 longVal1 = longVal0; |
| 300 } else { | 293 } else { |
| 301 longVal1 = -longVal0; | 294 longVal1 = -longVal0; |
| 302 } | 295 } |
| 303 } | 296 } |
| 304 _doTestBoolean(op, longVal0, longVal1); | 297 _doTestBoolean(op, longVal0, longVal1); |
| 305 } | 298 } |
| 306 } | 299 } |
| 307 | 300 |
| 301 void _doTestComparison(ComparisonOp op, int64 val0, int64 val1) { |
| 302 int ref = op.ref(val0.toInt(), val1.toInt()); |
| 303 int result = op.test(val0, val1); |
| 304 expect(ref == result, true, |
| 305 reason: "${op.name}: val0 = $val0, val1 = $val1"); |
| 306 } |
| 307 |
| 308 void doTestComparison(ComparisonOp op) { |
| 309 print("Testing operator ${op.name}"); |
| 310 for (int i = 0; i < TEST_VALUES.length; i++) { |
| 311 int64 randomLong = _randomInt64(); |
| 312 _doTestComparison(op, TEST_VALUES[i], randomLong); |
| 313 _doTestComparison(op, randomLong, TEST_VALUES[i]); |
| 314 for (int j = 0; j < TEST_VALUES.length; j++) { |
| 315 _doTestComparison(op, TEST_VALUES[i], TEST_VALUES[j]); |
| 316 } |
| 317 } |
| 318 for (int i = 0; i < RANDOM_TESTS; i++) { |
| 319 int64 longVal0 = _randomInt64(); |
| 320 int64 longVal1 = _randomInt64(); |
| 321 if (_randomInt(20) == 0) { |
| 322 if (_randomInt(2) == 0) { |
| 323 longVal1 = longVal0; |
| 324 } else { |
| 325 longVal1 = -longVal0; |
| 326 } |
| 327 } |
| 328 _doTestComparison(op, longVal0, longVal1); |
| 329 } |
| 330 } |
| 331 |
| 308 void _doTestShift(ShiftOp op, int64 val, int shift) { | 332 void _doTestShift(ShiftOp op, int64 val, int shift) { |
| 309 int ref = op.ref(val.toInt(), shift); | 333 int ref = op.ref(val.toInt(), shift); |
| 310 int64 result64 = op.test(val, shift); | 334 int64 result64 = op.test(val, shift); |
| 311 int result = result64.toInt(); | 335 int result = result64.toInt(); |
| 312 if (ref != result) { | 336 expect(ref == result, true, |
| 313 Expect.fail("${op.name}: val = $val, shift = $shift"); | 337 reason: "${op.name}: val = $val, shift = $shift"); |
| 314 } | |
| 315 } | 338 } |
| 316 | 339 |
| 317 void doTestShift(ShiftOp op) { | 340 void doTestShift(ShiftOp op) { |
| 318 print("Testing operator ${op.name}"); | 341 print("Testing operator ${op.name}"); |
| 319 for (int i = 0; i < TEST_VALUES.length; i++) { | 342 for (int i = 0; i < TEST_VALUES.length; i++) { |
| 320 for (int shift = -64; shift <= 64; shift++) { | 343 for (int shift = -64; shift <= 64; shift++) { |
| 321 _doTestShift(op, TEST_VALUES[i], shift); | 344 _doTestShift(op, TEST_VALUES[i], shift); |
| 322 } | 345 } |
| 323 } | 346 } |
| 324 for (int i = 0; i < RANDOM_TESTS; i++) { | 347 for (int i = 0; i < RANDOM_TESTS; i++) { |
| 325 int64 randomLong = _randomInt64(); | 348 int64 randomLong = _randomInt64(); |
| 326 for (int shift = -64; shift <= 64; shift++) { | 349 for (int shift = -64; shift <= 64; shift++) { |
| 327 _doTestShift(op, randomLong, shift); | 350 _doTestShift(op, randomLong, shift); |
| 328 } | 351 } |
| 329 } | 352 } |
| 330 } | 353 } |
| 331 } | 354 } |
| OLD | NEW |