diff --git a/tests/standalone/byte_array_view_optimized_test.dart b/tests/standalone/byte_array_view_optimized_test.dart new file mode 100644 index 00000000000..77b22d3b8b4 --- /dev/null +++ b/tests/standalone/byte_array_view_optimized_test.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test optimization of byte array views on external data. + +// Library tag to be able to run in html test framework. +library ByteArrayViewOptimizedTest; + +import "package:expect/expect.dart"; +import "dart:typed_data"; + +li16(v) => v[0]; + +main() { + var a = new Uint8List(2); + a[0] = a[1] = 0xff; + var b = new Int16List.view(a.buffer); + Expect.equals(-1, li16(b)); + for (var i = 0; i < 10000; i++) li16(b); + Expect.equals(-1, li16(b)); +} diff --git a/tests/standalone/bytedata_test.dart b/tests/standalone/bytedata_test.dart new file mode 100644 index 00000000000..7f8acf4766b --- /dev/null +++ b/tests/standalone/bytedata_test.dart @@ -0,0 +1,338 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart test program for testing typed data. + +// Library tag to be able to run in html test framework. +library ByteDataTest; + +import "package:expect/expect.dart"; +import 'dart:typed_data'; + +testGetters() { + bool host_is_little_endian = + (new Uint8List.view(new Uint16List.fromList([1]).buffer))[0] == 1; + + var list = new Uint8List(8); + list[0] = 0xf1; + list[1] = 0xf2; + list[2] = 0xf3; + list[3] = 0xf4; + list[4] = 0xf5; + list[5] = 0xf6; + list[6] = 0xf7; + list[7] = 0xf8; + var ba = list.buffer; + + ByteData bd = new ByteData.view(ba); + var value; + int expected_value_be = -3598; + int expected_value_le = -3343; + + value = bd.getInt16(0); // Default is big endian access. + Expect.equals(expected_value_be, value); + value = bd.getInt16(0, Endian.big); + Expect.equals(expected_value_be, value); + value = bd.getInt16(0, Endian.little); + Expect.equals(expected_value_le, value); + value = bd.getInt16(0, Endian.host); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + Expect.equals(expected_value_le, value); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + Expect.equals(expected_value_be, value); + } + + value = bd.getUint16(0); // Default is big endian access. + Expect.equals(0xf1f2, value); + value = bd.getUint16(0, Endian.big); + Expect.equals(0xf1f2, value); + value = bd.getUint16(0, Endian.little); + Expect.equals(0xf2f1, value); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + Expect.equals(0xf2f1, value); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + Expect.equals(0xf1f2, value); + } + + expected_value_be = -235736076; + expected_value_le = -185339151; + + value = bd.getInt32(0); // Default is big endian access. + Expect.equals(expected_value_be, value); + value = bd.getInt32(0, Endian.big); + Expect.equals(expected_value_be, value); + value = bd.getInt32(0, Endian.little); + Expect.equals(expected_value_le, value); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + Expect.equals(expected_value_le, value); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + Expect.equals(expected_value_be, value); + } + + value = bd.getUint32(0); // Default is big endian access. + Expect.equals(0xf1f2f3f4, value); + value = bd.getUint32(0, Endian.big); + Expect.equals(0xf1f2f3f4, value); + value = bd.getUint32(0, Endian.little); + Expect.equals(0xf4f3f2f1, value); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + Expect.equals(0xf4f3f2f1, value); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + Expect.equals(0xf1f2f3f4, value); + } + + expected_value_be = -1012478732780767240; + expected_value_le = -506664896818842895; + + value = bd.getInt64(0); // Default is big endian access. + Expect.equals(expected_value_be, value); + value = bd.getInt64(0, Endian.big); + Expect.equals(expected_value_be, value); + value = bd.getInt64(0, Endian.little); + Expect.equals(expected_value_le, value); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + Expect.equals(expected_value_le, value); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + Expect.equals(expected_value_be, value); + } + + value = bd.getUint64(0); // Default is big endian access. + Expect.equals(0xf1f2f3f4f5f6f7f8, value); + value = bd.getUint64(0, Endian.big); + Expect.equals(0xf1f2f3f4f5f6f7f8, value); + value = bd.getUint64(0, Endian.little); + Expect.equals(0xf8f7f6f5f4f3f2f1, value); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + Expect.equals(0xf8f7f6f5f4f3f2f1, value); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + Expect.equals(0xf1f2f3f4f5f6f7f8, value); + } + + double expected_be_value = -2.4060893954673178e+30; + double expected_le_value = -1.5462104171572421e+32; + value = bd.getFloat32(0); // Default is big endian access. + Expect.equals(expected_be_value, value); + value = bd.getFloat32(0, Endian.big); + Expect.equals(expected_be_value, value); + value = bd.getFloat32(0, Endian.little); + Expect.equals(expected_le_value, value); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + Expect.equals(expected_le_value, value); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + Expect.equals(expected_be_value, value); + } + + expected_be_value = -7.898661740976602e+240; + expected_le_value = -5.185705956736366e+274; + value = bd.getFloat64(0); // Default is big endian access. + Expect.equals(expected_be_value, value); + value = bd.getFloat64(0, Endian.big); + Expect.equals(expected_be_value, value); + value = bd.getFloat64(0, Endian.little); + Expect.equals(expected_le_value, value); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + Expect.equals(expected_le_value, value); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + Expect.equals(expected_be_value, value); + } +} + +validate16be(var list) { + Expect.equals(0xf1, list[0]); + Expect.equals(0xf2, list[1]); +} + +validate16le(var list) { + Expect.equals(0xf2, list[0]); + Expect.equals(0xf1, list[1]); +} + +validate32be(var list) { + Expect.equals(0xf1, list[0]); + Expect.equals(0xf2, list[1]); + Expect.equals(0xf3, list[2]); + Expect.equals(0xf4, list[3]); +} + +validate32le(var list) { + Expect.equals(0xf4, list[0]); + Expect.equals(0xf3, list[1]); + Expect.equals(0xf2, list[2]); + Expect.equals(0xf1, list[3]); +} + +validate64be(var list) { + Expect.equals(0xf1, list[0]); + Expect.equals(0xf2, list[1]); + Expect.equals(0xf3, list[2]); + Expect.equals(0xf4, list[3]); + Expect.equals(0xf5, list[4]); + Expect.equals(0xf6, list[5]); + Expect.equals(0xf7, list[6]); + Expect.equals(0xf8, list[7]); +} + +validate64le(var list) { + Expect.equals(0xf8, list[0]); + Expect.equals(0xf7, list[1]); + Expect.equals(0xf6, list[2]); + Expect.equals(0xf5, list[3]); + Expect.equals(0xf4, list[4]); + Expect.equals(0xf3, list[5]); + Expect.equals(0xf2, list[6]); + Expect.equals(0xf1, list[7]); +} + +testSetters() { + bool host_is_little_endian = + (new Uint8List.view(new Uint16List.fromList([1]).buffer))[0] == 1; + + var list = new Uint8List(8); + for (int i = 0; i < list.length; i++) { + list[i] = 0; + } + var ba = list.buffer; + ByteData bd = new ByteData.view(ba); + + bd.setInt16(0, 0xf1f2); // Default is big endian access. + validate16be(list); + bd.setInt16(0, 0xf1f2, Endian.big); + validate16be(list); + bd.setInt16(0, 0xf1f2, Endian.little); + validate16le(list); + bd.setInt16(0, 0xf1f2, Endian.host); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + validate16le(list); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + validate16be(list); + } + + bd.setUint16(0, 0xf1f2); // Default is big endian access. + validate16be(list); + bd.setUint16(0, 0xf1f2, Endian.big); + validate16be(list); + bd.setUint16(0, 0xf1f2, Endian.little); + validate16le(list); + bd.setUint16(0, 0xf1f2, Endian.host); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + validate16le(list); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + validate16be(list); + } + + bd.setInt32(0, 0xf1f2f3f4); // Default is big endian access. + validate32be(list); + bd.setInt32(0, 0xf1f2f3f4, Endian.big); + validate32be(list); + bd.setInt32(0, 0xf1f2f3f4, Endian.little); + validate32le(list); + bd.setInt32(0, 0xf1f2f3f4, Endian.host); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + validate32le(list); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + validate32be(list); + } + + bd.setUint32(0, 0xf1f2f3f4); // Default is big endian access. + validate32be(list); + bd.setUint32(0, 0xf1f2f3f4, Endian.big); + validate32be(list); + bd.setUint32(0, 0xf1f2f3f4, Endian.little); + validate32le(list); + bd.setUint32(0, 0xf1f2f3f4, Endian.host); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + validate32le(list); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + validate32be(list); + } + + bd.setInt64(0, 0xf1f2f3f4f5f6f7f8); // Default is big endian access. + validate64be(list); + bd.setInt64(0, 0xf1f2f3f4f5f6f7f8, Endian.big); + validate64be(list); + bd.setInt64(0, 0xf1f2f3f4f5f6f7f8, Endian.little); + validate64le(list); + bd.setInt64(0, 0xf1f2f3f4f5f6f7f8, Endian.host); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + validate64le(list); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + validate64be(list); + } + + bd.setUint64(0, 0xf1f2f3f4f5f6f7f8); // Default is big endian access. + validate64be(list); + bd.setUint64(0, 0xf1f2f3f4f5f6f7f8, Endian.big); + validate64be(list); + bd.setUint64(0, 0xf1f2f3f4f5f6f7f8, Endian.little); + validate64le(list); + bd.setUint64(0, 0xf1f2f3f4f5f6f7f8, Endian.host); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + validate64le(list); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + validate64be(list); + } + + bd.setFloat32(0, -2.4060893954673178e+30); // Default is big endian access. + validate32be(list); + bd.setFloat32(0, -2.4060893954673178e+30, Endian.big); + validate32be(list); + bd.setFloat32(0, -2.4060893954673178e+30, Endian.little); + validate32le(list); + bd.setFloat32(0, -2.4060893954673178e+30, Endian.host); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + validate32le(list); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + validate32be(list); + } + + bd.setFloat64(0, -7.898661740976602e+240); // Default is big endian access. + validate64be(list); + bd.setFloat64(0, -7.898661740976602e+240, Endian.big); + validate64be(list); + bd.setFloat64(0, -7.898661740976602e+240, Endian.little); + validate64le(list); + bd.setFloat64(0, -7.898661740976602e+240, Endian.host); + if (host_is_little_endian) { + Expect.isTrue(identical(Endian.host, Endian.little)); + validate64le(list); + } else { + Expect.isTrue(identical(Endian.host, Endian.big)); + validate64be(list); + } +} + +main() { + testGetters(); + testSetters(); +} diff --git a/tests/standalone/causal_async_stack_test.dart b/tests/standalone/causal_async_stack_test.dart new file mode 100644 index 00000000000..5b44becbd1c --- /dev/null +++ b/tests/standalone/causal_async_stack_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// VMOptions=--causal_async_stacks --no-lazy-async-stacks +// VMOptions=--no-causal_async_stacks --lazy-async-stacks + +import "package:expect/expect.dart"; + +noop() async => Future.value(null); + +baz() async { + // Throw exception after the first continuation, when there is no + // original stack trace. + await noop(); + throw "Bad!"; +} + +bar() async { + await baz(); +} + +foo() async { + await bar(); +} + +main() async { + try { + await foo(); + } catch (e, st) { + Expect.isTrue(st.toString().contains("baz")); + Expect.isTrue(st.toString().contains("bar")); + Expect.isTrue(st.toString().contains("foo")); + Expect.isTrue(st.toString().contains("main")); + } +} diff --git a/tests/standalone/check_class_cha_test.dart b/tests/standalone/check_class_cha_test.dart new file mode 100644 index 00000000000..50d6664352f --- /dev/null +++ b/tests/standalone/check_class_cha_test.dart @@ -0,0 +1,66 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; + +// Class hierarchy on an abstract class +// that defines a "next" structure. + +abstract class A { + A? next; +} + +class B extends A { + B(A? n) { + this.next = n; + } +} + +// Method that counts length of list. +// With only Bs, the getter can be +// inlined without check class. +int countMe(A? i) { + int x = 0; + while (i != null) { + A? next = i.next; + x++; + i = next; + } + return x; +} + +int doitHot(A? a) { + // Warm up the JIT. + int d = 0; + for (int i = 0; i < 1000; i++) { + d += countMe(a); + } + return d; +} + +// Nasty class that overrides the getter. +class C extends A { + C(A? n) { + this.next = n; + } + // New override. + A? get next => null; +} + +int bringInC(A? a) { + // Introduce C to compiler. + a = new C(a); + return doitHot(a); +} + +main() { + // Make a list with just Bs. + A? a = null; + for (int i = 0; i < 1000; i++) { + a = new B(a); + } + + Expect.equals(1000 * 1000, doitHot(a)); + Expect.equals(1000, bringInC(a)); +} diff --git a/tests/standalone/check_null_cha_test.dart b/tests/standalone/check_null_cha_test.dart new file mode 100644 index 00000000000..72017d226a2 --- /dev/null +++ b/tests/standalone/check_null_cha_test.dart @@ -0,0 +1,58 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; + +// A class the has a getter also provided by Object +// (higher in the class hierarchy) and thus also the +// Null class (besides X in the class hierarchy). +class X { + int hashCode = -1; + X() { + hashCode = 1; + } +} + +// Use this getter on X receiver. +int hashMe(X? x) { + int d = 0; + for (int i = 0; i < 10; i++) { + d += x.hashCode; + } + return d; +} + +// Use this getter on Null class receiver. +// Only possible value is null. +int hashNull(Null x) { + int d = 0; + for (int i = 0; i < 10; i++) { + d += x.hashCode; + } + return d; +} + +main() { + // Warm up the JIT with just an X object. Having a single receiver + // of type X with nothing below in the hierarchy that overrides + // hashCode could tempt the JIT to inline the getter with CHA + // that deopts when X is subclassed in the future. + X x = new X(); + for (int i = 0; i < 1000; i++) { + Expect.equals(10, hashMe(x)); + } + + // However, this is a special case that also works on null + // (calling Object's hashCode). So this should not throw an + // exception. Had we inlined, this would have hit the null + // check and thrown an exception. + Expect.notEquals(0, hashMe(null)); + + // Also warm up the JIT on a direct Null receiver. + int d = 0; + for (int i = 0; i < 1000; i++) { + d += hashNull(null); + } + Expect.notEquals(0, d); +} diff --git a/tests/standalone/constant_left_shift_test.dart b/tests/standalone/constant_left_shift_test.dart new file mode 100644 index 00000000000..5f87650577e --- /dev/null +++ b/tests/standalone/constant_left_shift_test.dart @@ -0,0 +1,78 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart test program for testing left shifts of a constant. + +import "package:expect/expect.dart"; + +shiftLeft0(c) => 0 << c; +shiftLeft1(c) => 1 << c; +shiftLeft8448(c) => 8448 << c; + +shiftLeftNeg1(c) => -1 << c; +shiftLeftNeg8448(c) => -8448 << c; + +main() { + // Optimize shifts. + for (int i = 0; i < 6000; i++) { + shiftLeft1(2); + shiftLeft0(2); + shiftLeft8448(2); + shiftLeftNeg1(2); + shiftLeftNeg8448(2); + } + for (int i = 0; i < 80; i++) { + Expect.equals(0, shiftLeft0(i)); + } + // Exceptions. + Expect.throws(() => shiftLeft0(-1)); + + Expect.equals(1, shiftLeft1(0)); + Expect.equals(128, shiftLeft1(7)); + Expect.equals(536870912, shiftLeft1(29)); + // Deoptimize on 32-bit. + Expect.equals(1073741824, shiftLeft1(30)); + Expect.equals(2147483648, shiftLeft1(31)); + Expect.equals(1152921504606846976, shiftLeft1(60)); + Expect.equals(2305843009213693952, shiftLeft1(61)); + // Deoptimize on 64 bits. + Expect.equals(4611686018427387904, shiftLeft1(62)); + Expect.equals(-9223372036854775808, shiftLeft1(63)); + + Expect.equals(8448, shiftLeft8448(0)); + Expect.equals(1081344, shiftLeft8448(7)); + Expect.equals(553648128, shiftLeft8448(16)); + // Deoptimize on 32-bit. + Expect.equals(1107296256, shiftLeft8448(17)); + Expect.equals(2214592512, shiftLeft8448(18)); + Expect.equals(1188950301625810944, shiftLeft8448(47)); + Expect.equals(2377900603251621888, shiftLeft8448(48)); + // Deoptimize on 64 bits. + Expect.equals(4755801206503243776, shiftLeft8448(49)); + Expect.equals(-8935141660703064064, shiftLeft8448(50)); + + Expect.equals(-1, shiftLeftNeg1(0)); + Expect.equals(-128, shiftLeftNeg1(7)); + Expect.equals(-536870912, shiftLeftNeg1(29)); + // Deoptimize on 32-bit. + Expect.equals(-1073741824, shiftLeftNeg1(30)); + Expect.equals(-2147483648, shiftLeftNeg1(31)); + Expect.equals(-1152921504606846976, shiftLeftNeg1(60)); + Expect.equals(-2305843009213693952, shiftLeftNeg1(61)); + // Deoptimize on 64 bits. + Expect.equals(-4611686018427387904, shiftLeftNeg1(62)); + Expect.equals(-9223372036854775808, shiftLeftNeg1(63)); + + Expect.equals(-8448, shiftLeftNeg8448(0)); + Expect.equals(-1081344, shiftLeftNeg8448(7)); + Expect.equals(-553648128, shiftLeftNeg8448(16)); + // Deoptimize on 32-bit. + Expect.equals(-1107296256, shiftLeftNeg8448(17)); + Expect.equals(-2214592512, shiftLeftNeg8448(18)); + Expect.equals(-1188950301625810944, shiftLeftNeg8448(47)); + Expect.equals(-2377900603251621888, shiftLeftNeg8448(48)); + // Deoptimize on 64 bits. + Expect.equals(-4755801206503243776, shiftLeftNeg8448(49)); + Expect.equals(8935141660703064064, shiftLeftNeg8448(50)); +} diff --git a/tests/standalone/dart_developer_disabled_env_test.dart b/tests/standalone/dart_developer_disabled_env_test.dart new file mode 100644 index 00000000000..1d9653baa41 --- /dev/null +++ b/tests/standalone/dart_developer_disabled_env_test.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// VMOptions=--no_causal_async_stacks + +import "package:expect/expect.dart"; + +main() { + Expect.isFalse( + const bool.fromEnvironment('dart.developer.causal_async_stacks')); +} diff --git a/tests/standalone/dart_developer_env2_test.dart b/tests/standalone/dart_developer_env2_test.dart new file mode 100644 index 00000000000..881880a3c43 --- /dev/null +++ b/tests/standalone/dart_developer_env2_test.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// VMOptions=--lazy-async-stacks --no-causal-async-stacks + +import "package:expect/expect.dart"; + +main() { + Expect.isFalse( + const bool.fromEnvironment('dart.developer.causal_async_stacks')); +} diff --git a/tests/standalone/dart_developer_env_test.dart b/tests/standalone/dart_developer_env_test.dart new file mode 100644 index 00000000000..abb7bf6c0d4 --- /dev/null +++ b/tests/standalone/dart_developer_env_test.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// VMOptions=--no-lazy-async-stacks --causal-async-stacks + +import "package:expect/expect.dart"; + +main() { + Expect + .isTrue(const bool.fromEnvironment('dart.developer.causal_async_stacks')); +} diff --git a/tests/standalone/deferred/alpha.dart b/tests/standalone/deferred/alpha.dart new file mode 100644 index 00000000000..20aac885a0c --- /dev/null +++ b/tests/standalone/deferred/alpha.dart @@ -0,0 +1,2 @@ +// beta.dart does not exist! +import 'beta.dart'; diff --git a/tests/standalone/deferred/exists.dart b/tests/standalone/deferred/exists.dart new file mode 100644 index 00000000000..26cc193fe6a --- /dev/null +++ b/tests/standalone/deferred/exists.dart @@ -0,0 +1 @@ +var x = 99; diff --git a/tests/standalone/deferred/transitive_error.dart b/tests/standalone/deferred/transitive_error.dart new file mode 100644 index 00000000000..e5a9af76251 --- /dev/null +++ b/tests/standalone/deferred/transitive_error.dart @@ -0,0 +1 @@ +import 'alpha.dart'; diff --git a/tests/standalone/deferred_transitive_import_error_test.dart b/tests/standalone/deferred_transitive_import_error_test.dart new file mode 100644 index 00000000000..585c9cde691 --- /dev/null +++ b/tests/standalone/deferred_transitive_import_error_test.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +// A deferred library that doesn't exist. +import 'package:foo/foo.dart' deferred as foo; +// A deferred library that does exist. +import 'deferred/exists.dart' deferred as exists; +// A deferred library that transitively will fail due to a file not found. +import 'deferred/transitive_error.dart' deferred as te; + +main() async { + // Attempt to load foo which will fail. + var fooError; + await foo.loadLibrary().catchError((e) { + fooError = e; + }); + Expect.isNotNull(fooError); + await exists.loadLibrary(); + Expect.equals(99, exists.x); + /* TODO(johnmccutchan): Implement transitive error reporting. + var teError; + await te.loadLibrary().catchError((e) { + teError = e; + }); + Expect.isNotNull(teError); + */ +} diff --git a/tests/standalone/deny_listed_test.dart b/tests/standalone/deny_listed_test.dart new file mode 100644 index 00000000000..2516b207683 --- /dev/null +++ b/tests/standalone/deny_listed_test.dart @@ -0,0 +1,59 @@ +// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Dart test checking that static/instance field shadowing do not conflict. + +// Test that certain interfaces/classes are denylisted from being +// implemented or extended (VM corelib only). + +library BlackListedTest; + +class MyBool extends Bool {} // //# 01: compile-time error + +class MyDouble extends Double {} // //# 02: compile-time error + +class MyObjectArray extends ObjectArray {} // //# 03: compile-time error + +class MyImmutableArray extends ImmutableArray {} // //# 04: compile-time error + +class MyGrowableObjectArray extends GrowableObjectArray {} // //# 05: compile-time error + +class MyIntegerImplementation extends IntegerImplementation {} // //# 06: compile-time error + +class MySmi extends Smi {} // //# 07: compile-time error + +class MyMint extends Mint {} // //# 08: compile-time error + +class MyBigint extends Bigint {} // //# 09: compile-time error + +class MyOneByteString extends OneByteString {} // //# 10: compile-time error + +class MyTwoByteString extends TwoByteString {} // //# 11: compile-time error + +class MyFourByteString extends FourByteString {} // //# 12: compile-time error + +main() { + new MyBool(); //# 01: continued + + new MyDouble(); //# 02: continued + + new MyObjectArray(); //# 03: continued + + new MyImmutableArray(); //# 04: continued + + new MyGrowableObjectArray(); //# 05: continued + + new MyIntegerImplementation(); //# 06: continued + + new MySmi(); //# 07: continued + + new MyMint(); //# 08: continued + + new MyBigint(); //# 09: continued + + new MyOneByteString(); //# 10: continued + + new MyTwoByteString(); //# 11: continued + + new MyFourByteString(); //# 12: continued +} diff --git a/tests/standalone/deoptimization_test.dart b/tests/standalone/deoptimization_test.dart new file mode 100644 index 00000000000..b60f7893c59 --- /dev/null +++ b/tests/standalone/deoptimization_test.dart @@ -0,0 +1,215 @@ +// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test deoptimization. + +import "package:expect/expect.dart"; + +class SmiCompares { + // Test deoptimization when one argument is known to be Smi. + static bool smiCompareLessThan2(a) { + return a < 2; + } + + // Test deoptimization when one argument is known to be Smi. + static bool smiCompareGreaterThan2(a) { + return 2 < a; + } + + // Test deoptimization when both arguments unknown. + static bool smiCompareLessThan(a, b) { + return a < b; + } + + // Test deoptimization when both arguments unknown. + static bool smiCompareGreaterThan(a, b) { + return a > b; + } + + static smiComparesTest() { + for (int i = 0; i < 2000; i++) { + Expect.equals(true, smiCompareLessThan2(1)); + Expect.equals(false, smiCompareLessThan2(3)); + Expect.equals(false, smiCompareGreaterThan2(1)); + Expect.equals(true, smiCompareGreaterThan2(3)); + Expect.equals(true, smiCompareLessThan(1, 2)); + Expect.equals(false, smiCompareGreaterThan(1, 2)); + } + // Deoptimize by passing a double instead of Smi + Expect.equals(true, smiCompareLessThan2(1.0)); + Expect.equals(false, smiCompareGreaterThan2(1.0)); + Expect.equals(true, smiCompareLessThan(1.0, 2)); + Expect.equals(false, smiCompareGreaterThan(1, 2.0)); + } +} + +class SmiBinop { + static subWithLiteral(a) { + return a - 1; + } + + static void smiBinopTest() { + for (int i = 0; i < 2000; i++) { + Expect.equals(2, subWithLiteral(3)); + } + // Deoptimize. + Expect.equals(2.0, subWithLiteral(3.0)); + } + + static mul(x) { + return x * 1024; + } + + static void smiBinopOverflowTest() { + final int big = 536870912; + for (int i = 0; i < 2000; i++) { + Expect.equals(1024, mul(1)); + } + // Deoptimize by overflow. + Expect.equals(1024 * big, mul(big)); + } +} + +class ObjectsEquality { + static bool compareEqual(a, b) { + return a == b; + } + + static bool compareNotEqual(a, b) { + return a != b; + } + + // Use only Object.==. + static void objectsEqualityTest() { + var a = new ObjectsEquality(); + var b = new ObjectsEquality(); + for (int i = 0; i < 1000; i++) { + Expect.equals(true, compareEqual(a, a)); + Expect.equals(true, compareEqual(null, null)); + Expect.equals(false, compareEqual(null, a)); + Expect.equals(false, compareEqual(a, null)); + Expect.equals(true, compareEqual(b, b)); + Expect.equals(false, compareEqual(a, b)); + + Expect.equals(false, compareNotEqual(a, a)); + Expect.equals(false, compareNotEqual(null, null)); + Expect.equals(true, compareNotEqual(null, a)); + Expect.equals(true, compareNotEqual(a, null)); + Expect.equals(false, compareNotEqual(b, b)); + Expect.equals(true, compareNotEqual(a, b)); + } + var c = new SmiBinop(); + // Deoptimize. + Expect.equals(true, compareEqual(c, c)); + Expect.equals(false, compareEqual(c, null)); + Expect.equals(false, compareNotEqual(c, c)); + Expect.equals(true, compareNotEqual(c, null)); + } +} + +class DeoptimizationTest { + static foo(a, b) { + return a - b; + } + + static test1() { + for (int i = 0; i < 2000; i++) { + Expect.equals(2, foo(3, 1)); // <-- Optimizes 'foo', + } + Expect.equals(2.2, foo(1.2, -1.0)); // <-- Deoptimizes 'foo'. + for (int i = 0; i < 10000; i++) { + Expect.equals(2, foo(3, 1)); // <-- Optimizes 'foo'. + } + Expect.equals(2.2, foo(1.2, -1)); // <-- Deoptimizes 'foo'. + } + + static moo(n) { + return ++n; + } + + static test2() { + for (int i = 0; i < 2000; i++) { + Expect.equals(4, moo(3)); // <-- Optimizes 'moo', + } + Expect.equals(2.2, moo(1.2)); // <-- Deoptimizes 'moo'. + for (int i = 0; i < 10000; i++) { + Expect.equals(4, moo(3)); // <-- Optimizes 'moo'. + } + Expect.equals(2.2, moo(1.2)); // <-- Deoptimizes 'moo'. + } + + static test3() { + for (int i = 0; i < 2000; i++) { + Expect.equals(2.0, foo(3.0, 1.0)); // <-- Optimizes 'foo', + } + Expect.equals(2, foo(1, -1)); // <-- Deoptimizes 'foo'. + for (int i = 0; i < 2000; i++) { + Expect.equals(2.0, foo(3.0, 1.0)); // <-- Optimizes 'foo', + } + Expect.equals(2.2, moo(1.2)); // <-- Deoptimizes 'moo'. + } + + static bool compareInt(a, b) { + return a < b; + } + + static bool compareDouble(a, b) { + return a < b; + } + + static test4() { + for (int i = 0; i < 2000; i++) { + Expect.equals(true, compareInt(1, 2)); + Expect.equals(true, compareDouble(1.0, 2.0)); + } + // Trigger deoptimization in compareInt and compareDouble. + Expect.equals(true, compareInt(1, 2.0)); + Expect.equals(true, compareDouble(1.0, 2)); + } + + static smiRightShift() { + int ShiftRight(int a, int b) { + return a >> b; + } + + for (int i = 0; i < 2000; i++) { + var r = ShiftRight(10, 2); + Expect.equals(2, r); + } + // ShiftRight is optimized. + Expect.equals(0, ShiftRight(10, 64)); + // Deoptimize ShiftRight because 'a' is a Mint. + var mint = 1 << 63; + Expect.equals(-1 << 3, ShiftRight(mint, 60)); + } + + static doubleUnary() { + num unary(num a) { + return -a; + } + + for (int i = 0; i < 2000; i++) { + var r = unary(2.0); + Expect.equals(-2.0, r); + } + var r = unary(5); + Expect.equals(-5, r); + } + + static void testMain() { + test1(); + test2(); + test3(); + test4(); + SmiCompares.smiComparesTest(); + SmiBinop.smiBinopTest(); + SmiBinop.smiBinopOverflowTest(); + ObjectsEquality.objectsEqualityTest(); + smiRightShift(); + doubleUnary(); + } +} + +main() { + DeoptimizationTest.testMain(); +} diff --git a/tests/standalone/double_hash_distribution_test.dart b/tests/standalone/double_hash_distribution_test.dart new file mode 100644 index 00000000000..1a66e17c942 --- /dev/null +++ b/tests/standalone/double_hash_distribution_test.dart @@ -0,0 +1,48 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test that the distribution of hash codes for doubles is reasonable. + +// VMOptions=--intrinsify +// VMOptions=--no_intrinsify + +import 'package:expect/expect.dart'; + +main() { + Expect.isTrue(ratio(0, 1) >= 0.95); + Expect.isTrue(ratio(0, 100) >= 0.95); + Expect.isTrue(ratio(0, 0xffffff) >= 0.95); + Expect.isTrue(ratio(0xffffff) >= 0.95); + Expect.isTrue(ratio(0xffffffff) >= 0.95); + Expect.isTrue(ratio(0xffffffffffffff) >= 0.95); + + Expect.isTrue(ratio(0, -1) >= 0.95); + Expect.isTrue(ratio(0, -100) >= 0.95); + Expect.isTrue(ratio(0, -0xffffff) >= 0.95); + Expect.isTrue(ratio(-0xffffff) >= 0.95); + Expect.isTrue(ratio(-0xffffffff) >= 0.95); + Expect.isTrue(ratio(-0xffffffffffffff) >= 0.95); +} + +double ratio(num start, [num? end]) { + final n = 1000; + end ??= (start + 1) * 2; + + // Collect the set of distinct doubles and the + // set of distinct hash codes. + final doubles = new Set(); + final codes = new Set(); + + final step = (end.toDouble() - start.toDouble()) / n; + var current = start.toDouble(); + for (int i = 0; i < n; i++) { + doubles.add(current); + codes.add(current.hashCode); + current += step; + } + + // Return the ratio between distinct doubles and + // distinct hash codes. + return codes.length / doubles.length; +} diff --git a/tests/standalone/double_smi_comparison_test.dart b/tests/standalone/double_smi_comparison_test.dart new file mode 100644 index 00000000000..fff6015e09e --- /dev/null +++ b/tests/standalone/double_smi_comparison_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test correct comparison (equality and relational) when mixing double and +// Smi arguments. We convert Smi to doubles and to the operation. This is +// not correct in 64-bit mode where not every Smi can be converted to a +// double without loss of precision. +// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation + +import "package:expect/expect.dart"; + +equalityFunc(a, b) => a == b; + +lessThanFunc(a, b) => a < b; + +main() { + for (int i = 0; i < 20; i++) { + Expect.isFalse(equalityFunc(1.0, 4)); + Expect.isTrue(lessThanFunc(1.0, 4)); + } + Expect.isFalse(equalityFunc(3459045988797251776, 3459045988797251777)); + Expect.isTrue(lessThanFunc(3459045988797251776, 3459045988797251777)); +} diff --git a/tests/standalone/double_temp_test.dart b/tests/standalone/double_temp_test.dart new file mode 100644 index 00000000000..da55ef37981 --- /dev/null +++ b/tests/standalone/double_temp_test.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test correct usage of inlined double temporary objects. + +import "package:expect/expect.dart"; + +main() { + for (int i = 0; i < 2000; i++) { + testBinaryOp(); + testUnaryOp(); + } +} + +// VM: temporary double should not be used as result of division, +// otherwise the function always returns the same object. +double divide(double a, double b) { + return a / b; +} + +testBinaryOp() { + var x = divide(1.0, 2.0); + var y = divide(2.0, 3.0); + Expect.notEquals(x, y); +} + +// VM: temporary double should be used only for "-b", otherwise the +// function would always return the same object. +double unary(double a, double b) { + return -(a * (-b)); +} + +testUnaryOp() { + var x = unary(1.0, 2.0); + var y = unary(3.0, 4.0); + Expect.equals(2.0, x); + Expect.equals(12.0, y); +} diff --git a/tests/standalone/double_to_int_test.dart b/tests/standalone/double_to_int_test.dart new file mode 100644 index 00000000000..d2207a9b1dc --- /dev/null +++ b/tests/standalone/double_to_int_test.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Tests optimization: transform double.toInt() to DoubleToSmi +// unless we encounter a non-Smi result, in which case we deoptimize and +// optimize it later to DoubleToInt. + +import "package:expect/expect.dart"; + +main() { + for (int i = 0; i < 600; i++) { + Expect.equals(100, foo(100, 1.2)); + } + // Deoptimize 'foo', d2smi -> d2int. + Expect.equals(36507222016 * 2, foo(2, 36507222016.6)); + for (int i = 0; i < 600; i++) { + Expect.equals(100, foo(100, 1.2)); + } + Expect.equals(36507222016 * 2, foo(2, 36507222016.6)); +} + +foo(n, a) { + int k = 0; + for (int i = 0; i < n; i++) { + k += goo(a); + } + return k; +} + +int goo(a) { + return a.toInt(); +} diff --git a/tests/standalone/entrypoints_verification_test.dart b/tests/standalone/entrypoints_verification_test.dart new file mode 100644 index 00000000000..cfc8058f1f4 --- /dev/null +++ b/tests/standalone/entrypoints_verification_test.dart @@ -0,0 +1,107 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// VMOptions=--verify-entry-points=true + +import 'dart:io'; +import 'dart:convert'; +import 'dart:math'; +import 'package:path/path.dart'; +import 'package:expect/expect.dart'; +import 'dart-ext:entrypoints_verification_test_extension'; + +void RunTest() native "RunTest"; + +main() { + RunTest(); + + new C(); + new D(); +} + +class C {} + +@pragma("vm:entry-point") +class D { + D(); + + @pragma("vm:entry-point") + D.defined(); + + @pragma("vm:entry-point") + factory D.fact() => E.ctor(); + + void fn0() {} + + @pragma("vm:entry-point") + void fn1() {} + + @pragma("vm:entry-point", "get") + void fn1_get() {} + + @pragma("vm:entry-point", "call") + void fn1_call() {} + + static void fn2() {} + + @pragma("vm:entry-point") + static void fn3() {} + + @pragma("vm:entry-point", "call") + static void fn3_call() {} + + @pragma("vm:entry-point", "get") + static void fn3_get() {} + + void Function()? fld0; + + @pragma("vm:entry-point") + void Function()? fld1; + + @pragma("vm:entry-point", "get") + void Function()? fld2; + + @pragma("vm:entry-point", "set") + void Function()? fld3; +} + +void fn0() {} + +@pragma("vm:entry-point") +void fn1() {} + +@pragma("vm:entry-point", "get") +void fn1_get() {} + +@pragma("vm:entry-point", "call") +void fn1_call() {} + +class E extends D { + E.ctor(); +} + +@pragma("vm:entry-point") +class F { + static void Function()? fld0; + + @pragma("vm:entry-point") + static void Function()? fld1; + + @pragma("vm:entry-point", "get") + static void Function()? fld2; + + @pragma("vm:entry-point", "set") + static void Function()? fld3; +} + +void Function()? fld0; + +@pragma("vm:entry-point") +void Function()? fld1; + +@pragma("vm:entry-point", "get") +void Function()? fld2; + +@pragma("vm:entry-point", "set") +void Function()? fld3; diff --git a/tests/standalone/env_test.dart b/tests/standalone/env_test.dart new file mode 100644 index 00000000000..6280f60987d --- /dev/null +++ b/tests/standalone/env_test.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// SharedOptions=-Dvar -D -D=var -Dvar=invalid -Dvar=valid -Dvar + +import "package:expect/expect.dart"; + +main() { + Expect.equals('valid', const String.fromEnvironment('var')); +} diff --git a/tests/standalone/fields_may_be_reset_test.dart b/tests/standalone/fields_may_be_reset_test.dart new file mode 100644 index 00000000000..3ab6fc62450 --- /dev/null +++ b/tests/standalone/fields_may_be_reset_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--fields_may_be_reset + +main() { + print("Okay"); +} diff --git a/tests/standalone/float_array_static_test.dart b/tests/standalone/float_array_static_test.dart new file mode 100644 index 00000000000..1c89b9658e3 --- /dev/null +++ b/tests/standalone/float_array_static_test.dart @@ -0,0 +1,56 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart test program for testing native float arrays. + +// VMOptions=--optimization_counter_threshold=10 --no-background_compilation + +// Library tag to be able to run in html test framework. +library FloatArrayTest; + +import "package:expect/expect.dart"; +import 'dart:typed_data'; + +void testIndexOf32() { + var list = new Float32List(10); + for (int i = 0; i < list.length; i++) { + list[i] = i + 10.0; + } + /*@compile-error=unspecified*/ Expect.equals(0, list.indexOf(10)); + /*@compile-error=unspecified*/ Expect.equals(5, list.indexOf(15)); + /*@compile-error=unspecified*/ Expect.equals(9, list.indexOf(19)); + /*@compile-error=unspecified*/ Expect.equals(-1, list.indexOf(20)); +} + +void testBadValues32() { + var list = new Float32List(10); + list[0] = 2.0; + /*@compile-error=unspecified*/ list[0] = 2; + /*@compile-error=unspecified*/ list[0] = "hello"; +} + +void testIndexOf64() { + var list = new Float64List(10); + for (int i = 0; i < list.length; i++) { + list[i] = i + 10.0; + } + /*@compile-error=unspecified*/ Expect.equals(0, list.indexOf(10)); + /*@compile-error=unspecified*/ Expect.equals(5, list.indexOf(15)); + /*@compile-error=unspecified*/ Expect.equals(9, list.indexOf(19)); + /*@compile-error=unspecified*/ Expect.equals(-1, list.indexOf(20)); +} + +void testBadValues64() { + var list = new Float64List(10); + list[0] = 2.0; + /*@compile-error=unspecified*/ list[0] = 2; + /*@compile-error=unspecified*/ list[0] = "hello"; +} + +main() { + testIndexOf32(); + testIndexOf64(); + testBadValues32(); + testBadValues64(); +} diff --git a/tests/standalone/float_array_test.dart b/tests/standalone/float_array_test.dart new file mode 100644 index 00000000000..a7e78421a4b --- /dev/null +++ b/tests/standalone/float_array_test.dart @@ -0,0 +1,186 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart test program for testing native float arrays. + +// VMOptions=--optimization_counter_threshold=10 --no-background_compilation + +// Library tag to be able to run in html test framework. +library FloatArrayTest; + +import "package:expect/expect.dart"; +import 'dart:typed_data'; + +void testCreateFloat32Array() { + Float32List floatArray; + + floatArray = new Float32List(0); + Expect.equals(0, floatArray.length); + + floatArray = new Float32List(10); + Expect.equals(10, floatArray.length); + for (int i = 0; i < 10; i++) { + Expect.equals(0.0, floatArray[i]); + } +} + +void testSetRange32() { + Float32List floatArray = new Float32List(3); + + List list = [10.0, 11.0, 12.0]; + floatArray.setRange(0, 3, list); + for (int i = 0; i < 3; i++) { + Expect.equals(10 + i, floatArray[i]); + } + + floatArray[0] = 20.0; + floatArray[1] = 21.0; + floatArray[2] = 22.0; + list.setRange(0, 3, floatArray); + for (int i = 0; i < 3; i++) { + Expect.equals(20 + i, list[i]); + } + + // 4.0e40 is larger than the largest representable float. + floatArray.setRange(1, 3, const [8.0, 4.0e40]); + Expect.equals(20, floatArray[0]); + Expect.equals(8, floatArray[1]); + Expect.equals(double.infinity, floatArray[2]); +} + +void testIndexOutOfRange32() { + Float32List floatArray = new Float32List(3); + List list = const [0.0, 1.0, 2.0, 3.0]; + + Expect.throws(() { + floatArray[5] = 2.0; + }); + Expect.throws(() { + floatArray.setRange(0, 4, list); + }); + + Expect.throws(() { + floatArray.setRange(3, 4, list); + }); +} + +void testIndexOf32() { + var list = new Float32List(10); + for (int i = 0; i < list.length; i++) { + list[i] = i + 10.0; + } + Expect.equals(0, list.indexOf(10.0)); + Expect.equals(5, list.indexOf(15.0)); + Expect.equals(9, list.indexOf(19.0)); + Expect.equals(-1, list.indexOf(20.0)); +} + +void testCreateFloat64Array() { + Float64List floatArray; + + floatArray = new Float64List(0); + Expect.equals(0, floatArray.length); + + floatArray = new Float64List(10); + Expect.equals(10, floatArray.length); + for (int i = 0; i < 10; i++) { + Expect.equals(0.0, floatArray[i]); + } +} + +void testSetRange64() { + Float64List floatArray = new Float64List(3); + + List list = [10.0, 11.0, 12.0]; + floatArray.setRange(0, 3, list); + for (int i = 0; i < 3; i++) { + Expect.equals(10 + i, floatArray[i]); + } + + floatArray[0] = 20.0; + floatArray[1] = 21.0; + floatArray[2] = 22.0; + list.setRange(0, 3, floatArray); + for (int i = 0; i < 3; i++) { + Expect.equals(20 + i, list[i]); + } + + // Unlike Float32Array we can properly represent 4.0e40 + floatArray.setRange(1, 3, const [8.0, 4.0e40]); + Expect.equals(20, floatArray[0]); + Expect.equals(8, floatArray[1]); + Expect.equals(4.0e40, floatArray[2]); +} + +void testIndexOutOfRange64() { + Float64List floatArray = new Float64List(3); + List list = const [0.0, 1.0, 2.0, 3.0]; + + Expect.throws(() { + floatArray[5] = 2.0; + }); + Expect.throws(() { + floatArray.setRange(0, 4, list); + }); + + Expect.throws(() { + floatArray.setRange(3, 4, list); + }); +} + +void testIndexOf64() { + var list = new Float64List(10); + for (int i = 0; i < list.length; i++) { + list[i] = i + 10.0; + } + Expect.equals(0, list.indexOf(10.0)); + Expect.equals(5, list.indexOf(15.0)); + Expect.equals(9, list.indexOf(19.0)); + Expect.equals(-1, list.indexOf(20.0)); +} + +storeIt32(Float32List a, int index, value) { + a[index] = value; +} + +storeIt64(Float64List a, int index, value) { + a[index] = value; +} + +testPolymorphicLoad(var list) { + return list[0]; +} + +main() { + var a32 = new Float32List(5); + for (int i = 0; i < 20; i++) { + testCreateFloat32Array(); + testSetRange32(); + testIndexOutOfRange32(); + testIndexOf32(); + storeIt32(a32, 1, 2.0); + testPolymorphicLoad(a32); + } + var a64 = new Float64List(5); + for (int i = 0; i < 20; i++) { + testCreateFloat64Array(); + testSetRange64(); + testIndexOutOfRange64(); + testIndexOf64(); + storeIt64(a64, 1, 2.0); + testPolymorphicLoad(a64); + } + var f32x4 = new Float32x4List(5); + for (int i = 0; i < 20; i++) { + testPolymorphicLoad(f32x4); + } + + // Check optimized (inlined) version of []= + Expect.throws(() { + storeIt32(a32, 1, 2); + }); + Expect.throws(() { + storeIt64(a64, 1, 2); + }); +} diff --git a/tests/standalone/fragmentation_test.dart b/tests/standalone/fragmentation_test.dart new file mode 100644 index 00000000000..04f21c46fcf --- /dev/null +++ b/tests/standalone/fragmentation_test.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Deliberately fragment the heap and test that GC peformance does not +// break down. See https://github.com/dart-lang/sdk/issues/29588 +// Normally runs in about 6-7 seconds on an x64 machine, using about 2.5Gbytes +// of memory. +// +// This test is deliberately CPU-light and so it can make a lot of +// progress before the concurrent sweepers are done sweeping the heap. +// In that time there is no freelist and so the issue does not arise. +// VMOptions=--no_concurrent_mark --no_concurrent_sweep +// VMOptions=--no_concurrent_mark --concurrent_sweep +// VMOptions=--no_concurrent_mark --use_compactor +// VMOptions=--no_concurrent_mark --use_compactor --force_evacuation +// VMOptions=--concurrent_mark --no_concurrent_sweep +// VMOptions=--concurrent_mark --concurrent_sweep +// VMOptions=--concurrent_mark --use_compactor +// VMOptions=--concurrent_mark --use_compactor --force_evacuation +// VMOptions=--scavenger_tasks=0 +// VMOptions=--scavenger_tasks=1 +// VMOptions=--scavenger_tasks=2 +// VMOptions=--scavenger_tasks=3 + +main() { + final List arrays = []; + // Fill up heap with alternate large-small items. + for (int i = 0; i < 500000; i++) { + arrays.add(new List.filled(260, null)); + arrays.add(new List.filled(1, null)); + } + // Clear the large items so that the heap is full of 260-word gaps. + for (int i = 0; i < arrays.length; i += 2) { + arrays[i] = null; + } + // Allocate a lot of 300-word objects that don't fit in the gaps. + for (int i = 0; i < 600000; i++) { + arrays.add(new List.filled(300, null)); + } +} diff --git a/tests/standalone/fragmentation_typed_data_test.dart b/tests/standalone/fragmentation_typed_data_test.dart new file mode 100644 index 00000000000..c4577f2cdec --- /dev/null +++ b/tests/standalone/fragmentation_typed_data_test.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// See fragmentation_test.dart for more information. +// +// VMOptions=--no_concurrent_mark --no_concurrent_sweep +// VMOptions=--no_concurrent_mark --concurrent_sweep +// VMOptions=--no_concurrent_mark --use_compactor +// VMOptions=--no_concurrent_mark --use_compactor --force_evacuation +// VMOptions=--concurrent_mark --no_concurrent_sweep +// VMOptions=--concurrent_mark --concurrent_sweep +// VMOptions=--concurrent_mark --use_compactor +// VMOptions=--concurrent_mark --use_compactor --force_evacuation + +import 'dart:io'; +import 'dart:typed_data'; + +main() { + // We have less memory available on the Android testing devices, and if we + // allocate to much the kernel may summarily terminate us. + final double factor = Platform.isAndroid ? 0.5 : 1.0; + + final List arrays = []; + // Fill up heap with alternate large-small items. + for (int i = 0; i < 500000 * factor; i++) { + arrays.add(new Uint32List(260)); + arrays.add(new Uint32List(1)); + } + // Clear the large items so the heap has large gaps. + for (int i = 0; i < arrays.length; i += 2) { + arrays[i] = null; + } + // Allocate a lot of large items which don't fit in the gaps created above. + for (int i = 0; i < 600000 * factor; i++) { + arrays.add(new Uint32List(300)); + } +} diff --git a/tests/standalone/http_launch_data/.dart_tool/package_config.json b/tests/standalone/http_launch_data/.dart_tool/package_config.json new file mode 100644 index 00000000000..6ff2893f310 --- /dev/null +++ b/tests/standalone/http_launch_data/.dart_tool/package_config.json @@ -0,0 +1,9 @@ +{ + "configVersion": 2, + "packages": [ + { + "name": "simple", + "rootUri": "../the_packages/simple" + } + ] +} diff --git a/tests/standalone/http_launch_data/.packages b/tests/standalone/http_launch_data/.packages new file mode 100644 index 00000000000..4d7ff273737 --- /dev/null +++ b/tests/standalone/http_launch_data/.packages @@ -0,0 +1 @@ +simple:the_packages/simple diff --git a/tests/standalone/http_launch_data/http_isolate_main.dart b/tests/standalone/http_launch_data/http_isolate_main.dart new file mode 100644 index 00000000000..ad6306ab1e0 --- /dev/null +++ b/tests/standalone/http_launch_data/http_isolate_main.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:isolate'; + +main(List args, SendPort replyTo) { + var data = args[0]; + replyTo.send(data); +} diff --git a/tests/standalone/http_launch_data/http_launch_main.dart b/tests/standalone/http_launch_data/http_launch_main.dart new file mode 100644 index 00000000000..f9a5b521d81 --- /dev/null +++ b/tests/standalone/http_launch_data/http_launch_main.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library http_launch_main; + +import 'package:simple/simple.dart'; + +main() { + print(getSimpleString()); +} diff --git a/tests/standalone/http_launch_data/http_spawn_main.dart b/tests/standalone/http_launch_data/http_spawn_main.dart new file mode 100644 index 00000000000..e6b1a24ff79 --- /dev/null +++ b/tests/standalone/http_launch_data/http_spawn_main.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library http_launch_main; + +import 'dart:isolate'; +import 'dart:io'; + +main(List arguments) { + int port = int.parse(arguments[0]); + ReceivePort receivePort = new ReceivePort(); + Isolate.spawnUri(Uri.parse('http://127.0.0.1:$port/http_isolate_main.dart'), + ['hello'], receivePort.sendPort); + receivePort.first.then((response) { + print(response); + }); +} diff --git a/tests/standalone/http_launch_data/the_packages/simple/simple.dart b/tests/standalone/http_launch_data/the_packages/simple/simple.dart new file mode 100644 index 00000000000..1a7e7e0fa49 --- /dev/null +++ b/tests/standalone/http_launch_data/the_packages/simple/simple.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library simple; + +String getSimpleString() => 'hello'; diff --git a/tests/standalone/http_launch_test.dart b/tests/standalone/http_launch_test.dart new file mode 100644 index 00000000000..1c9f8abebcf --- /dev/null +++ b/tests/standalone/http_launch_test.dart @@ -0,0 +1,112 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// VMOptions= +// VMOptions=--short_socket_read +// VMOptions=--short_socket_write +// VMOptions=--short_socket_read --short_socket_write +// OtherResources=http_launch_data/http_isolate_main.dart +// OtherResources=http_launch_data/http_launch_main.dart +// OtherResources=http_launch_data/http_spawn_main.dart +// OtherResources=http_launch_data/the_packages/simple/simple.dart +// OtherResources=http_launch_data/.packages +// +// Test: +// *) Launching a script fetched over HTTP. +// *) Importing a library fetched over HTTP. +// *) Automatically resolving package_root when script is fetched over HTTP. +// *) Spawning a URI over HTTP. + +library http_launch_test; + +import 'dart:async'; +import 'dart:io'; +import 'package:expect/expect.dart'; + +String pathToExecutable = Platform.executable; +List executableArguments = Platform.executableArguments + .where((arg) => !arg.startsWith('--packages=')) + .toList(); +Uri pathOfData = Platform.script.resolve('http_launch_data/'); +late int port; + +_sendNotFound(HttpResponse response) { + response.statusCode = HttpStatus.notFound; + response.close(); +} + +handleRequest(HttpRequest request) { + final String path = request.uri.path.substring(1); + final Uri requestPath = pathOfData.resolve(path); + final File file = new File(requestPath.toFilePath()); + file.exists().then((bool found) { + if (found) { + file.openRead().cast>().pipe(request.response).catchError((e) { + _sendNotFound(request.response); + }); + } else { + _sendNotFound(request.response); + } + }); +} + +serverRunning(HttpServer server) { + port = server.port; + server.listen(handleRequest); + Future no_http_run = Process.run( + pathToExecutable, + [] + ..addAll(executableArguments) + ..add(pathOfData.resolve('http_launch_main.dart').toFilePath())); + Future http_run = Process.run( + pathToExecutable, + [] + ..addAll(executableArguments) + ..add('http://127.0.0.1:$port/http_launch_main.dart')); + Future http_pkg_root_run = Process.run( + pathToExecutable, + [] + ..addAll(executableArguments) + ..addAll(['http://127.0.0.1:$port/http_launch_main.dart'])); + Future isolate_run = Process.run( + pathToExecutable, + [] + ..addAll(executableArguments) + ..addAll(['http://127.0.0.1:$port/http_spawn_main.dart', '$port'])); + Future> results = + Future.wait([no_http_run, http_run, http_pkg_root_run, isolate_run]); + results.then((results) { + // Close server. + server.close(); + // Check results. + checkResults(results); + }); +} + +checkResults(List results) { + Expect.equals(4, results.length); + // Exited cleanly. + for (int i = 0; i < results.length; i++) { + ProcessResult result = results[i]; + if (result.exitCode != 0) { + print("Exit code for process $i = ${result.exitCode}"); + print("---stdout:---\n${result.stdout}"); + print("---stderr:---\n${result.stderr}\n---"); + } + Expect.equals(0, result.exitCode); + } + String stdout = results[0].stdout; + // Output is the string 'hello'. Use startsWith to avoid new line differences. + if (!stdout.startsWith('hello')) { + print("---- stdout of remote process:\n$stdout\n----"); + } + Expect.isTrue(stdout.startsWith('hello')); + // Same output from all three process runs. + for (int i = 0; i < results.length; i++) { + Expect.equals(stdout, results[i].stdout); + } +} + +main() { + HttpServer.bind(InternetAddress.loopbackIPv4, 0).then(serverRunning); +} diff --git a/tests/standalone/int_array_deopt.dart b/tests/standalone/int_array_deopt.dart new file mode 100644 index 00000000000..7a2b9698a1b --- /dev/null +++ b/tests/standalone/int_array_deopt.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart deoptimization of Uint32Array and Int32Array loads. + +import 'dart:typed_data'; +import "package:expect/expect.dart"; + +loadI32(a) => a[0] + 1; +loadUi32(a) => a[0] + 1; + +main() { + var i32 = new Int32List(10); + var ui32 = new Uint32List(10); + i32[0] = ui32[0] = 8; + // Optimize loadI32 and LoadUi32 for Smi result of indexed load. + for (int i = 0; i < 2000; i++) { + Expect.equals(9, loadI32(i32)); + Expect.equals(9, loadUi32(ui32)); + } + // On ia32, deoptimize when attempting to load a value that exceeds + // Smi range. + i32[0] = ui32[0] = 2147483647; + Expect.equals(2147483648, loadI32(i32)); + Expect.equals(2147483648, loadUi32(ui32)); + // Reoptimize again, but this time assume mixed Smi/Mint results + i32[0] = ui32[0] = 10; + for (int i = 0; i < 2000; i++) { + Expect.equals(11, loadI32(i32)); + Expect.equals(11, loadUi32(ui32)); + } +} diff --git a/tests/standalone/int_array_load_elimination_test.dart b/tests/standalone/int_array_load_elimination_test.dart new file mode 100644 index 00000000000..4e8dea6a3c4 --- /dev/null +++ b/tests/standalone/int_array_load_elimination_test.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Test correct load elimination for scalar lists. + +// TODO: remove once bug 2264 fixed. +library int_array_load_elimination; + +import "package:expect/expect.dart"; +import 'dart:typed_data'; + +void testUint16() { + Uint16List intArray = new Uint16List(1); + intArray[0] = -1; + var x = intArray[0]; + Expect.equals(65535, x); +} + +main() { + for (int i = 0; i < 2000; i++) { + testUint16(); + } +} diff --git a/tests/standalone/int_array_test.dart b/tests/standalone/int_array_test.dart new file mode 100644 index 00000000000..30d326ac9b5 --- /dev/null +++ b/tests/standalone/int_array_test.dart @@ -0,0 +1,139 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart test program for testing native int arrays. + +// Library tag to be able to run in html test framework. +library IntArrayTest; + +import "package:expect/expect.dart"; +import 'dart:typed_data'; + +void testInt16() { + Int16List intArray = new Int16List(4); + intArray[0] = 0; + intArray[1] = -1; + intArray[2] = -2; + intArray[3] = -3; + for (int i = 0; i < intArray.length; i++) { + intArray[i]++; + } + var x = intArray[0]; + var y = intArray[1]; + var z = intArray[2]; + var w = intArray[3]; + Expect.equals(1, x); + Expect.equals(0, y); + Expect.equals(-1, z); + Expect.equals(-2, w); + var t = y + 1; + intArray[0] = t; + Expect.equals(t, intArray[0]); +} + +void testUint16() { + Uint16List intArray = new Uint16List(4); + intArray[0] = 0; + intArray[1] = 1; + intArray[2] = 2; + intArray[3] = 3; + for (int i = 0; i < intArray.length; i++) { + intArray[i]--; + } + var x = intArray[0]; + var y = intArray[1]; + var z = intArray[2]; + var w = intArray[3]; + Expect.equals(65535, x); + Expect.equals(0, y); + Expect.equals(1, z); + Expect.equals(2, w); + var t = y + 1; + intArray[0] = t; + Expect.equals(t, intArray[0]); +} + +void testInt32ToSmi() { + Int32List intArray; + + intArray = new Int32List(4); + intArray[0] = 1073741823; // SmiMax + intArray[1] = -1073741824; // SmiMin + intArray[2] = 1073741824; // SmiMax+1 + intArray[3] = -1073741825; // SmiMin-1 + var x = intArray[0]; + var y = intArray[1]; + var z = intArray[2]; + var w = intArray[3]; + Expect.equals(1073741823, x); + Expect.equals(-1073741824, y); + Expect.equals(1073741824, z); + Expect.equals(-1073741825, w); +} + +void testUint32ToSmi() { + Uint32List intArray; + + intArray = new Uint32List(4); + intArray[0] = 1073741823; // SmiMax + intArray[1] = -1; // 0xFFFFFFFF : 4294967295 + intArray[2] = 1073741830; // SmiMax+7 + intArray[3] = -1073741825; // 0xbfffffff : 3221225471 + var x = intArray[0]; + var y = intArray[1]; + var z = intArray[2]; + var w = intArray[3]; + Expect.equals(1073741823, x); + Expect.equals(4294967295, y); + Expect.equals(1073741830, z); + Expect.equals(3221225471, w); +} + +void testInt64ToSmi() { + Int64List intArray; + + intArray = new Int64List(4); + intArray[0] = 4611686018427387903; // SmiMax + intArray[1] = -4611686018427387904; // SmiMin + intArray[2] = 4611686018427387904; // SmiMax+1 + intArray[3] = -4611686018427387905; // SmiMin-1 + var x = intArray[0]; + var y = intArray[1]; + var z = intArray[2]; + var w = intArray[3]; + Expect.equals(4611686018427387903, x); + Expect.equals(-4611686018427387904, y); + Expect.equals(4611686018427387904, z); + Expect.equals(-4611686018427387905, w); +} + +void testUint64ToSmi() { + Uint64List intArray; + + intArray = new Uint64List(4); + intArray[0] = 4611686018427387903; // SmiMax + intArray[1] = -1; // 0xFFFFFFFFFFFFFFFF : 18446744073709551615 + intArray[2] = 4611686018427387904; // SmiMax+1 + intArray[3] = -9223372036854775808; + var x = intArray[0]; + var y = intArray[1]; + var z = intArray[2]; + var w = intArray[3]; + Expect.equals(4611686018427387903, x); + Expect.equals(-1, y); + Expect.equals(4611686018427387904, z); + Expect.equals(-9223372036854775808, w); +} + +main() { + testUint64ToSmi(); + for (int i = 0; i < 2000; i++) { + testInt16(); + testUint16(); + testInt32ToSmi(); + testUint32ToSmi(); + testInt64ToSmi(); + testUint64ToSmi(); + } +} diff --git a/tests/standalone/int_list_test.dart b/tests/standalone/int_list_test.dart new file mode 100644 index 00000000000..c719f4d14b0 --- /dev/null +++ b/tests/standalone/int_list_test.dart @@ -0,0 +1,42 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart Mint representations and type propagation issue. +// Testing Int32List and Uint32List loads. +// +// VMOptions=--optimization-counter-threshold=5 --no-use-osr --no-background-compilation + +import 'dart:typed_data'; +import "package:expect/expect.dart"; + +main() { + var a = new Uint32List(100); + a[2] = 3; + var res = sumIt1(a, 2); + Expect.equals(3 * 10, res); + res = sumIt1(a, 2); + Expect.equals(3 * 10, res); + var a1 = new Int32List(100); + a1[2] = 3; + res = sumIt2(a1, 2); + Expect.equals(3 * 10, res); + res = sumIt2(a1, 2); + Expect.equals(3 * 10, res); +} + +sumIt1(Uint32List a, int n) { + var sum = 0; + for (int i = 0; i < 10; i++) { + sum += a[n]; + } + return sum; +} + +sumIt2(Int32List a, int n) { + var sum = 0; + for (int i = 0; i < 10; i++) { + sum += a[n]; + } + return sum; +} diff --git a/tests/standalone/left_shift_bit_and_op_test.dart b/tests/standalone/left_shift_bit_and_op_test.dart new file mode 100644 index 00000000000..9140ceb9e4f --- /dev/null +++ b/tests/standalone/left_shift_bit_and_op_test.dart @@ -0,0 +1,80 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Tests optimizing (a << b) & c if c is a Smi constant. + +import "package:expect/expect.dart"; + +main() { + checkshiftAnd32(); + checkShiftAnd64(); + // Optimize shiftAnd32. + for (int i = 0; i < 10000; i++) { + A.shiftAnd32(12, 17); + A.shiftAnd64(12, 17); + Expect.equals(72, A.multipleConstantUses(3, 4)); + Expect.equals(34493956096, A.multipleShiftUse(134742016, 8)); + } + checkshiftAnd32(); + checkShiftAnd64(); + + Expect.throws(() => A.shiftAnd32(12, -5)); + + // Check environment dependency. + final a = new A(), b = new B(); + for (var i = 0; i < 10000; i++) { + Expect.equals(0, bar(a)); + } + Expect.equals(4294967296, bar(b)); +} + +checkshiftAnd32() { + Expect.equals(1572864, A.shiftAnd32(12, 17)); + Expect.equals(12, A.shiftAnd32(12, 0)); + Expect.equals(285212672, A.shiftAnd32(16779392, 17)); +} + +checkShiftAnd64() { + Expect.equals(1125936481173504, A.shiftAnd64(4611694814806147072, 7)); +} + +class A { + static const int MASK_32 = (1 << 30) - 1; + static const int MASK_64 = (1 << 62) - 1; + + static shiftAnd32(a, c) { + return (a << c) & MASK_32; + } + + static shiftAnd64(a, c) { + return (a << c) & MASK_64; + } + + static multipleConstantUses(a, c) { + var j = (a << c) & 0xFF; + var k = (a << 3) & 0xFF; + return j + k; + } + + // Make sure that left shift is nor marked as truncating. + static multipleShiftUse(a, c) { + var y = (a << c); + var x = y & 0x7F; + return y + x; + } + + foo(x) { + return x & 0xf; + } +} + +class B { + foo(x) { + return x; + } +} + +bar(o) { + return o.foo(1 << 32); +} diff --git a/tests/standalone/link_natives_lazily_test.dart b/tests/standalone/link_natives_lazily_test.dart new file mode 100644 index 00000000000..35a53a13411 --- /dev/null +++ b/tests/standalone/link_natives_lazily_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--link_natives_lazily + +main() { + print("Okay"); +} diff --git a/tests/standalone/map_insert_remove_oom_test.dart b/tests/standalone/map_insert_remove_oom_test.dart new file mode 100644 index 00000000000..143fd18ab4b --- /dev/null +++ b/tests/standalone/map_insert_remove_oom_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// VMOptions=--old_gen_heap_size=12 +// +// Notice we set the old gen heap size to 12 MB, which seems to be the minimum +// (in debug mode) to not cause us run OOM during isolate initialization. The +// problem here is that we pre-allocate certain exceptions, e.g. NullThrownError +// during isolate initialization, but if we have an allocation failure before +// that, we end up running into a recursive allocate/throw loop. +// +// Test that compaction does occur on repeated add/remove. + +main() { + var x = {}; + for (int i = 0; i < 1000000; i++) { + x[i] = 10; + x.remove(i); + } +} diff --git a/tests/standalone/medium_integer_test.dart b/tests/standalone/medium_integer_test.dart new file mode 100644 index 00000000000..28532f9b43e --- /dev/null +++ b/tests/standalone/medium_integer_test.dart @@ -0,0 +1,108 @@ +// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Testing Mints. Note that the tests may not work on 64-bit machines, +// as Smi's would be used to represent many of the numbers. + +library MediumIntegerTest; + +import "package:expect/expect.dart"; + +class MediumIntegerTest { + static int getMint() { + return 1234567890123456789; + } + + static testSmiOverflow() { + int a = 1073741823; + int b = 1073741822; + Expect.equals(2147483645, a + b); + Expect.equals(1152921501385621506, a * b); + Expect.equals(-2147483645, -a - b); + } + + static testMintAdd() { + // Mint and Smi. + var a = 1234567890123456789; + var b = 2; + Expect.equals(1234567890123456791, a + b); + Expect.equals(1234567890123456791, b + a); + a = 9223372036854775807; + Expect.equals(-9223372036854775808, a + 1); + + // Mint and Mint. + a = 100000000000000001; + Expect.equals(200000000000000002, a + a); + a = 9223372036854775800; + b = 1000000000000000000; + Expect.equals(-8223372036854775816, a + b); + + // Mint and double. + var da = 100000000000.0; + b = 100000000000; + Expect.equals(200000000000.0, da + b); + Expect.equals(200000000000.0, b + da); + } + + static testMintSub() { + // Mint and Smi. + var a = 1234567890123456789; + var b = 2; + Expect.equals(1234567890123456787, a - b); + a = -9223372036854775808; + Expect.equals(9223372036854775807, a - 1); + + // Mint and Mint. + a = 1234567890123456789; + b = 1000000000000000000; + Expect.equals(234567890123456789, a - b); + a = -9223372036854775808; + b = 1000000000000000000; + Expect.equals(8223372036854775808, a - b); + } + + static testMintDiv() { + // Mint and Smi. + var a = 1234567890123456788; + var b = 2; + Expect.equals(617283945061728394.0, a / b); + } + + static testMintMul() { + // Mint and Smi. + var a = 4611686018427387904; + var b = 10; + Expect.equals(-9223372036854775808, a * b); + b = 1000000000000000000; + Expect.equals(0, a * b); + } + + static testMintAnd(mint) { + // Issue 1845. + final int t = 0; + var res = mint & (t - 1); + Expect.equals(mint, res); + } + + static void testMain() { + Expect.equals(1234567890123456789, getMint()); + testSmiOverflow(); + testMintAdd(); + testMintSub(); + testMintMul(); + testMintDiv(); + testMintAnd(-1925149952); + testMintAnd(1925149952); + testMintAnd(0x100000001); + var a = 100000000000; + var b = 100000000001; + Expect.equals(false, a.hashCode == b.hashCode); + Expect.equals(true, a.hashCode == (b - 1).hashCode); + } +} + +main() { + for (int i = 0; i < 4000; i++) { + MediumIntegerTest.testMain(); + } +} diff --git a/tests/standalone/no_allow_absolute_addresses_test.dart b/tests/standalone/no_allow_absolute_addresses_test.dart new file mode 100644 index 00000000000..e013c5e80a7 --- /dev/null +++ b/tests/standalone/no_allow_absolute_addresses_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--no_allow_absolute_addresses + +main() { + print("Okay"); +} diff --git a/tests/standalone/no_lazy_dispatchers_test.dart b/tests/standalone/no_lazy_dispatchers_test.dart new file mode 100644 index 00000000000..f45ba1c402d --- /dev/null +++ b/tests/standalone/no_lazy_dispatchers_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--no_lazy_dispatchers + +main() { + print("Okay"); +} diff --git a/tests/standalone/no_profiler_test.dart b/tests/standalone/no_profiler_test.dart new file mode 100644 index 00000000000..0b612d1700b --- /dev/null +++ b/tests/standalone/no_profiler_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--no_profiler + +main() { + print("Okay"); +} diff --git a/tests/standalone/no_support_ast_printer_test.dart b/tests/standalone/no_support_ast_printer_test.dart new file mode 100644 index 00000000000..bbffe225493 --- /dev/null +++ b/tests/standalone/no_support_ast_printer_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--no-support_ast_printer + +main() { + print("Okay"); +} diff --git a/tests/standalone/no_support_debugger_test.dart b/tests/standalone/no_support_debugger_test.dart new file mode 100644 index 00000000000..fb20c9ab95d --- /dev/null +++ b/tests/standalone/no_support_debugger_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--no-support_debugger + +main() { + print("Okay"); +} diff --git a/tests/standalone/no_support_disassembler_test.dart b/tests/standalone/no_support_disassembler_test.dart new file mode 100644 index 00000000000..2f0aca0308f --- /dev/null +++ b/tests/standalone/no_support_disassembler_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--no_support_disassembler + +main() { + print("Okay"); +} diff --git a/tests/standalone/no_support_il_printer_test.dart b/tests/standalone/no_support_il_printer_test.dart new file mode 100644 index 00000000000..4ebba33e30a --- /dev/null +++ b/tests/standalone/no_support_il_printer_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--no-support_il_printer + +main() { + print("Okay"); +} diff --git a/tests/standalone/no_support_service_test.dart b/tests/standalone/no_support_service_test.dart new file mode 100644 index 00000000000..2431dbc2fd0 --- /dev/null +++ b/tests/standalone/no_support_service_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--no-support_service + +main() { + print("Okay"); +} diff --git a/tests/standalone/no_support_timeline_test.dart b/tests/standalone/no_support_timeline_test.dart new file mode 100644 index 00000000000..c15a4419f75 --- /dev/null +++ b/tests/standalone/no_support_timeline_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--no-support_timeline + +main() { + print("Okay"); +} diff --git a/tests/standalone/number_identity_test.dart b/tests/standalone/number_identity_test.dart new file mode 100644 index 00000000000..ce9cbfe03eb --- /dev/null +++ b/tests/standalone/number_identity_test.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Dart test program for testing params. +// +// Tests 'identical' for cases that not supported in dart2js (bigint, +// disambiguation int/double). + +import "package:expect/expect.dart"; + +main() { + for (int i = 0; i < 1000; i++) testNumberIdentity(); +} + +testNumberIdentity() { + const int smi = 8; + const int mint = 9223372036854775807; + const double dbl = 8.0; + // No int/double differences in dart2js. + var a = smi + 0; + Expect.isFalse(identical(a, dbl)); + var c = dbl + 0.0; + Expect.isFalse(identical(c, smi)); + + a = mint; + var b = a + 0; + Expect.isTrue(identical(a, b)); + b = a + 1; + Expect.isFalse(identical(a, b)); // Fails with dart2js. +} diff --git a/tests/standalone/oom_error_stacktrace_test.dart b/tests/standalone/oom_error_stacktrace_test.dart new file mode 100644 index 00000000000..c9289e35868 --- /dev/null +++ b/tests/standalone/oom_error_stacktrace_test.dart @@ -0,0 +1,49 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Dart test program for testing throw statement +// VMOptions=--old_gen_heap_size=512 + +import "package:expect/expect.dart"; + +class Helper1 { + static int func1() { + return func2(); + } + + static int func2() { + return func3(); + } + + static int func3() { + return func4(); + } + + static int func4() { + var i = 0; + try { + i = 10; + func5(); + } on OutOfMemoryError catch (e) { + i = 100; + Expect.isNull(e.stackTrace, "OOM should not have a stackTrace on throw"); + } + return i; + } + + static List func5() { + // Cause an OOM(out of memory) exception. + var l1 = new List.filled(268435455, null); + return l1; + } +} + +class OOMErrorStackTraceTest { + static testMain() { + Expect.equals(100, Helper1.func1()); + } +} + +main() { + OOMErrorStackTraceTest.testMain(); +} diff --git a/tests/standalone/out_of_memory_test.dart b/tests/standalone/out_of_memory_test.dart new file mode 100644 index 00000000000..0b85a9fa294 --- /dev/null +++ b/tests/standalone/out_of_memory_test.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// VMOptions=--old_gen_heap_size=512 + +import "package:expect/expect.dart"; + +void main() { + var number_of_ints = 134000000; + var exception_thrown = false; + try { + List buf = new List.filled(number_of_ints, -1); + } on OutOfMemoryError catch (exc) { + exception_thrown = true; + } + Expect.isTrue(exception_thrown); +} diff --git a/tests/standalone/package/invalid_uri_test.dart b/tests/standalone/package/invalid_uri_test.dart new file mode 100644 index 00000000000..c08186015f0 --- /dev/null +++ b/tests/standalone/package/invalid_uri_test.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library invalid_uri_test; + + // Should not contain "//". +import 'package://lib1.dart'; //# 01: compile-time error + +void main() {} diff --git a/tests/standalone/package/package1_test.dart b/tests/standalone/package/package1_test.dart new file mode 100644 index 00000000000..53c88286f7a --- /dev/null +++ b/tests/standalone/package/package1_test.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=none + +library package1_test; + +import 'package:package1.dart' as p1; + +main() { + p1.main(); +} diff --git a/tests/standalone/package/package_isolate_test.dart b/tests/standalone/package/package_isolate_test.dart new file mode 100644 index 00000000000..2a30cb5540c --- /dev/null +++ b/tests/standalone/package/package_isolate_test.dart @@ -0,0 +1,49 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library package_isolate_test; + +import 'packages/shared.dart' as shared; +import 'dart:isolate'; +import '../../../pkg/async_helper/lib/async_helper.dart'; +import '../../../pkg/expect/lib/expect.dart'; + +expectResponse() { + asyncStart(); + var receivePort = new ReceivePort(); + receivePort.first.then((msg) { + Expect.equals('isolate', msg); + Expect.equals('main', shared.output); + asyncEnd(); + }); + return receivePort; +} + +void main() { + { + var replyPort = expectResponse().sendPort; + shared.output = 'main'; + Isolate.spawn(isolate_main, replyPort); + } + + { + // Package in spawnUri() of sibling file. + var replyPort = expectResponse().sendPort; + shared.output = 'main'; + Isolate.spawnUri(Uri.parse('sibling_isolate.dart'), [], replyPort); + } + + { + // Package in spawnUri() of file in folder. + var replyPort = expectResponse().sendPort; + shared.output = 'main'; + Isolate.spawnUri( + Uri.parse('test_folder/folder_isolate.dart'), [], replyPort); + } +} + +void isolate_main(SendPort replyTo) { + shared.output = 'isolate'; + replyTo.send(shared.output); +} diff --git a/tests/standalone/package/package_test.dart b/tests/standalone/package/package_test.dart new file mode 100644 index 00000000000..4f7e52b4c44 --- /dev/null +++ b/tests/standalone/package/package_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=none + +library package_test; + +import 'package:lib1.dart'; +import 'package:shared.dart'; + +void main() { + output = 'main'; + // Call an imported lib, which will in turn call some others. + lib1(); + + // Make sure they were all reached successfully. + if (output != 'main|lib1|lib2|lib3') { + throw new Error("libraries were not reached successfully"); + } +} diff --git a/tests/standalone/package/scenarios/both_dir_and_file/.packages b/tests/standalone/package/scenarios/both_dir_and_file/.packages new file mode 100644 index 00000000000..17ae735b318 --- /dev/null +++ b/tests/standalone/package/scenarios/both_dir_and_file/.packages @@ -0,0 +1 @@ +foo:foo/ \ No newline at end of file diff --git a/tests/standalone/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart b/tests/standalone/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart new file mode 100644 index 00000000000..53195a7e2f1 --- /dev/null +++ b/tests/standalone/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=none + +library both_dir_and_file_noimports_test; + +main() {} diff --git a/tests/standalone/package/scenarios/both_dir_and_file/foo/foo.dart b/tests/standalone/package/scenarios/both_dir_and_file/foo/foo.dart new file mode 100644 index 00000000000..8e60bcd5164 --- /dev/null +++ b/tests/standalone/package/scenarios/both_dir_and_file/foo/foo.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library foo; + +String bar = 'good'; diff --git a/tests/standalone/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart b/tests/standalone/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart new file mode 100644 index 00000000000..f06fc567dc9 --- /dev/null +++ b/tests/standalone/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=none + +library prefers_packages_file_test; + +import 'package:foo/foo.dart' as foo; + +main() { + if (foo.bar != 'good') { + throw new Exception('package "foo" was not resolved correctly'); + } +} diff --git a/tests/standalone/package/scenarios/empty_packages_file/.packages b/tests/standalone/package/scenarios/empty_packages_file/.packages new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_discovery_test.dart b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_discovery_test.dart new file mode 100644 index 00000000000..5b5156e26a5 --- /dev/null +++ b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_discovery_test.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=none + +library empty_packages_file_discovery_test; + +import 'package:foo/foo.dart'; + +main() {} diff --git a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart new file mode 100644 index 00000000000..af76de87b61 --- /dev/null +++ b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=.packages + +// We expect this to not cause any errors. An empty packages file is valid, +// you should only run into problems if you try to resolve a package import. +library empty_packages_file_noimports_test; + +main() {} diff --git a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart new file mode 100644 index 00000000000..010f5f3db45 --- /dev/null +++ b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=.packages + +library empty_packages_file_option_test; + +import 'package:foo/foo.dart'; + +main() {} diff --git a/tests/standalone/package/scenarios/invalid/foo/foo.dart b/tests/standalone/package/scenarios/invalid/foo/foo.dart new file mode 100644 index 00000000000..8c5c0467904 --- /dev/null +++ b/tests/standalone/package/scenarios/invalid/foo/foo.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library foo; + +String foo = 'foo'; diff --git a/tests/standalone/package/scenarios/invalid/invalid_package_name.packages b/tests/standalone/package/scenarios/invalid/invalid_package_name.packages new file mode 100644 index 00000000000..d74d280256d --- /dev/null +++ b/tests/standalone/package/scenarios/invalid/invalid_package_name.packages @@ -0,0 +1,2 @@ +..:nonexistent/ +foo:foo/ \ No newline at end of file diff --git a/tests/standalone/package/scenarios/invalid/invalid_package_name_test.dart b/tests/standalone/package/scenarios/invalid/invalid_package_name_test.dart new file mode 100644 index 00000000000..4c278c99dec --- /dev/null +++ b/tests/standalone/package/scenarios/invalid/invalid_package_name_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=invalid_package_name.packages + +library invalid_package_name_test; + +import 'package:foo/foo.dart' as foo; + +main() { + if (foo.foo != 'foo') { + throw new Exception('package "foo" was not resolved correctly'); + } +} diff --git a/tests/standalone/package/scenarios/invalid/invalid_utf8.packages b/tests/standalone/package/scenarios/invalid/invalid_utf8.packages new file mode 100644 index 00000000000..b0c09d0d15f --- /dev/null +++ b/tests/standalone/package/scenarios/invalid/invalid_utf8.packages @@ -0,0 +1 @@ +þ:foo/ diff --git a/tests/standalone/package/scenarios/invalid/invalid_utf8_test.dart b/tests/standalone/package/scenarios/invalid/invalid_utf8_test.dart new file mode 100644 index 00000000000..224fc8851df --- /dev/null +++ b/tests/standalone/package/scenarios/invalid/invalid_utf8_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=invalid_utf8.packages + +library invalid_utf8_test; + +main() {} diff --git a/tests/standalone/package/scenarios/invalid/non_existent_packages_file_test.dart b/tests/standalone/package/scenarios/invalid/non_existent_packages_file_test.dart new file mode 100644 index 00000000000..dc7380c11c3 --- /dev/null +++ b/tests/standalone/package/scenarios/invalid/non_existent_packages_file_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=non_existent.packages + +library non_existent_packages_file_test; + +main() {} diff --git a/tests/standalone/package/scenarios/invalid/same_package_twice.packages b/tests/standalone/package/scenarios/invalid/same_package_twice.packages new file mode 100644 index 00000000000..bdd57b6894d --- /dev/null +++ b/tests/standalone/package/scenarios/invalid/same_package_twice.packages @@ -0,0 +1,3 @@ +foo:nonexistentdir/ +# This overrides the previous entry +foo:foo/ \ No newline at end of file diff --git a/tests/standalone/package/scenarios/invalid/same_package_twice_test.dart b/tests/standalone/package/scenarios/invalid/same_package_twice_test.dart new file mode 100644 index 00000000000..acedb40ab8e --- /dev/null +++ b/tests/standalone/package/scenarios/invalid/same_package_twice_test.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=same_package_twice.packages + +library same_package_twice_test; + +import 'package:foo/foo.dart' as foo; + +main() {} diff --git a/tests/standalone/package/scenarios/packages_file_in_parent/.packages b/tests/standalone/package/scenarios/packages_file_in_parent/.packages new file mode 100644 index 00000000000..17ae735b318 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_in_parent/.packages @@ -0,0 +1 @@ +foo:foo/ \ No newline at end of file diff --git a/tests/standalone/package/scenarios/packages_file_in_parent/foo/foo.dart b/tests/standalone/package/scenarios/packages_file_in_parent/foo/foo.dart new file mode 100644 index 00000000000..fed9bd7ef2f --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_in_parent/foo/foo.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library foo; + +String bar = 'hello'; diff --git a/tests/standalone/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_noimports_test.dart b/tests/standalone/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_noimports_test.dart new file mode 100644 index 00000000000..d5194f14d2a --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_noimports_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=none + +library packages_file_in_parent_noimports_test; + +main() {} diff --git a/tests/standalone/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_test.dart b/tests/standalone/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_test.dart new file mode 100644 index 00000000000..0151f194f94 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=none + +library packages_file_in_parent_test; + +import 'package:foo/foo.dart' as foo; + +main() { + if (foo.bar != 'hello') { + throw new Exception('package "foo" was not resolved correctly'); + } +} diff --git a/tests/standalone/package/scenarios/packages_file_only/.packages b/tests/standalone/package/scenarios/packages_file_only/.packages new file mode 100644 index 00000000000..17ae735b318 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_only/.packages @@ -0,0 +1 @@ +foo:foo/ \ No newline at end of file diff --git a/tests/standalone/package/scenarios/packages_file_only/foo/foo.dart b/tests/standalone/package/scenarios/packages_file_only/foo/foo.dart new file mode 100644 index 00000000000..fed9bd7ef2f --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_only/foo/foo.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library foo; + +String bar = 'hello'; diff --git a/tests/standalone/package/scenarios/packages_file_only/packages_file_only_noimports_test.dart b/tests/standalone/package/scenarios/packages_file_only/packages_file_only_noimports_test.dart new file mode 100644 index 00000000000..e495256c039 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_only/packages_file_only_noimports_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=none + +library packages_file_only_noimports_test; + +main() {} diff --git a/tests/standalone/package/scenarios/packages_file_only/packages_file_only_test.dart b/tests/standalone/package/scenarios/packages_file_only/packages_file_only_test.dart new file mode 100644 index 00000000000..554f3b71e23 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_only/packages_file_only_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=none + +library packages_file_only_test; + +import 'package:foo/foo.dart' as foo; + +main() { + if (foo.bar != 'hello') { + throw new Exception('package "foo" was not resolved correctly'); + } +} diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/bar/bar.dart b/tests/standalone/package/scenarios/packages_file_strange_formatting/bar/bar.dart new file mode 100644 index 00000000000..7ff2cb059f0 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/bar/bar.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library bar; + +String bar = 'bar'; diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/baz/baz.dart b/tests/standalone/package/scenarios/packages_file_strange_formatting/baz/baz.dart new file mode 100644 index 00000000000..54059cbaad9 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/baz/baz.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library baz; + +String baz = 'baz'; diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines.packages b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines.packages new file mode 100644 index 00000000000..e81099e5abf --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines.packages @@ -0,0 +1,20 @@ + + + + +foo:foo/ + + +bar:bar/ + + + + + + + + +baz:baz/ + + + diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines_test.dart b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines_test.dart new file mode 100644 index 00000000000..665597a8fef --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=empty_lines.packages + +library empty_lines_test; + +import 'package:foo/foo.dart' as foo; +import 'package:bar/bar.dart' as bar; +import 'package:baz/baz.dart' as baz; + +main() { + if (foo.foo != 'foo') { + throw new Exception('package "foo" was not resolved correctly'); + } + if (bar.bar != 'bar') { + throw new Exception('package "bar" was not resolved correctly'); + } + if (baz.baz != 'baz') { + throw new Exception('package "baz" was not resolved correctly'); + } +} diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages new file mode 100644 index 00000000000..0152a79652d --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages @@ -0,0 +1 @@ +foo: diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir_test.dart b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir_test.dart new file mode 100644 index 00000000000..97cded4e10c --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=empty_package_dir.packages + +// In this test, we give a packages file that associates the package 'foo' with +// the empty string. This causes both the VM and dart2js to resolve +// 'package:foo' imports relative to the root directory. So the import statement +// `import 'package:foo/foo.dart'` is equivalent to `import '/foo.dart'`. +library empty_package_dir_test; + +import 'package:foo/foo.dart'; + +main() {} diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/foo/foo.dart b/tests/standalone/package/scenarios/packages_file_strange_formatting/foo/foo.dart new file mode 100644 index 00000000000..8c5c0467904 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/foo/foo.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library foo; + +String foo = 'foo'; diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages b/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages new file mode 100644 index 00000000000..c3d3e75d940 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages @@ -0,0 +1,3 @@ +foo:foo/ +bar:bar/ +baz:baz/ diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends_test.dart b/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends_test.dart new file mode 100644 index 00000000000..3e9ec48c993 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=mixed_line_ends.packages + +library mixed_line_ends_test; + +import 'package:foo/foo.dart' as foo; +import 'package:bar/bar.dart' as bar; +import 'package:baz/baz.dart' as baz; + +main() { + if (foo.foo != 'foo') { + throw new Exception('package "foo" was not resolved correctly'); + } + if (bar.bar != 'bar') { + throw new Exception('package "bar" was not resolved correctly'); + } + if (baz.baz != 'baz') { + throw new Exception('package "baz" was not resolved correctly'); + } +} diff --git a/tests/standalone/package/scenarios/packages_option_only/packages_option_only_noimports_test.dart b/tests/standalone/package/scenarios/packages_option_only/packages_option_only_noimports_test.dart new file mode 100644 index 00000000000..92e1cac85a2 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_option_only/packages_option_only_noimports_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=sub/.packages + +library packages_option_only_noimports_test; + +main() {} diff --git a/tests/standalone/package/scenarios/packages_option_only/packages_option_only_test.dart b/tests/standalone/package/scenarios/packages_option_only/packages_option_only_test.dart new file mode 100644 index 00000000000..47fdcdecd2a --- /dev/null +++ b/tests/standalone/package/scenarios/packages_option_only/packages_option_only_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Packages=sub/.packages + +library packages_option_only_test; + +import 'package:foo/foo.dart' as foo; + +main() { + if (foo.bar != 'hello') { + throw new Exception('package "foo" was not resolved correctly'); + } +} diff --git a/tests/standalone/package/scenarios/packages_option_only/sub/.packages b/tests/standalone/package/scenarios/packages_option_only/sub/.packages new file mode 100644 index 00000000000..17ae735b318 --- /dev/null +++ b/tests/standalone/package/scenarios/packages_option_only/sub/.packages @@ -0,0 +1 @@ +foo:foo/ \ No newline at end of file diff --git a/tests/standalone/package/scenarios/packages_option_only/sub/foo/foo.dart b/tests/standalone/package/scenarios/packages_option_only/sub/foo/foo.dart new file mode 100644 index 00000000000..fed9bd7ef2f --- /dev/null +++ b/tests/standalone/package/scenarios/packages_option_only/sub/foo/foo.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library foo; + +String bar = 'hello'; diff --git a/tests/standalone/package/sibling_isolate.dart b/tests/standalone/package/sibling_isolate.dart new file mode 100644 index 00000000000..134196ec58e --- /dev/null +++ b/tests/standalone/package/sibling_isolate.dart @@ -0,0 +1,14 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library sibling_isolate; + +import 'package:shared.dart' as shared; +import 'dart:isolate'; + +// This file is spawned from package_isolate_test.dart +main(List args, SendPort reply) { + shared.output = 'isolate'; + reply.send(shared.output); +} diff --git a/tests/standalone/package/test_folder/folder_isolate.dart b/tests/standalone/package/test_folder/folder_isolate.dart new file mode 100644 index 00000000000..4a564488ef9 --- /dev/null +++ b/tests/standalone/package/test_folder/folder_isolate.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library folder_isolate; + +// This is a package that's not available to the main isolate +import 'package:folder_lib.dart' as isolate_package; +import 'dart:isolate'; + +// This file is spawned from package_isolate_test.dart +main(List args, Sendport replyTo) { + isolate_package.count = 1; + replyTo.send('isolate'); +} diff --git a/tests/standalone/packages_file_test.dart b/tests/standalone/packages_file_test.dart new file mode 100644 index 00000000000..99c2ab5203c --- /dev/null +++ b/tests/standalone/packages_file_test.dart @@ -0,0 +1,1011 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--enable-isolate-groups +// VMOptions=--no-enable-isolate-groups + +import "dart:async"; +import "dart:io"; +import "dart:convert" show json; +import "package:path/path.dart" as p; +import "package:async_helper/async_helper.dart"; + +/// Root directory of generated files. +/// Path contains trailing slash. +/// Each configuration gets its own sub-directory. +Directory fileRoot; + +/// Shared HTTP server serving the files in [httpFiles]. +/// Each configuration gets its own "sub-dir" entry in `httpFiles`. +HttpServer httpServer; + +/// Directory structure served by HTTP server. +Map httpFiles = {}; + +/// List of configurations. +List configurations = []; + +/// Collection of failing tests and their failure messages. +/// +/// Each test may fail in more than one way. +var failingTests = >{}; + +main() async { + asyncStart(); + await setUp(); + + await runTests(); // //# 01: ok + await runTests([spawn]); // //# 02: ok + await runTests([spawn, spawn]); // //# 03: ok + await runTests([spawnUriInherit]); // //# 04: ok + await runTests([spawnUriInherit, spawn]); // //# 05: ok + await runTests([spawn, spawnUriInherit]); // //# 06: ok + + // Test that spawning a new VM with file paths instead of URIs as arguments + // gives the same URIs in the internal values. + await runTests([asPath]); // //# 07: ok + + // Test that spawnUri can reproduce the behavior of VM command line parameters + // exactly. + // (Don't run all configuration combinations in the same test, so + // unroll the configurations into multiple groups and run each group + // as its own multitest. + { + var groupCount = 8; + var groups = new List.generate(8, (_) => []); + for (int i = 0; i < configurations.length; i++) { + groups[i % groupCount].add(configurations[i]); + } + var group = -1; + group = 0; // //# 10: ok + group = 1; // //# 11: ok + group = 2; // //# 12: ok + group = 3; // //# 13: ok + group = 4; // //# 14: ok + group = 5; // //# 15: ok + group = 6; // //# 16: ok + group = 7; // //# 17: ok + if (group >= 0) { + for (var other in groups[group]) { + await runTests([spawnUriOther(other)]); + } + } + } + + await tearDown(); + + if (failingTests.isNotEmpty) { + print("Errors found in tests:"); + failingTests.forEach((test, actual) { + print("$test:\n ${actual.join("\n ")}"); + }); + exit(255); + } + + asyncEnd(); +} + +/// Test running the test of the configuration through [Isolate.spawn]. +/// +/// This should not change the expected results compared to running it +/// directly. +Configuration spawn(Configuration conf) { + return conf.update( + description: conf.description + "/spawn", + main: "spawnMain", + newArgs: [conf.mainType], + expect: null); +} + +/// Tests running a spawnUri on top of the configuration before testing. +/// +/// The `spawnUri` call has no explicit root or config parameter, and +/// shouldn't search for one, so it implicitly inherits the current isolate's +/// actual root or configuration. +Configuration spawnUriInherit(Configuration conf) { + if (conf.expect["iroot"] == null && + conf.expect["iconf"] == null && + conf.expect["pconf"] != null) { + // This means that the specified configuration file didn't exist. + // spawning a new URI to "inherit" that will actually do an automatic + // package resolution search with results that are unpredictable. + // That behavior will be tested in a setting where we have more control over + // the files around the spawned URI. + return null; + } + return conf.update( + description: conf.description + "/spawnUri-inherit", + main: "spawnUriMain", + // encode null parameters as "-". Windows fails if using empty string. + newArgs: [ + conf.mainFile, + "-", + "-", + "false" + ], + expect: { + "proot": conf.expect["iroot"], + "pconf": conf.expect["iconf"], + }); +} + +/// Tests running a spawnUri with an explicit configuration different +/// from the original configuration. +/// +/// Duplicates the explicit parameters as arguments to the spawned isolate. +ConfigurationTransformer spawnUriOther(Configuration other) { + return (Configuration conf) { + bool search = (other.config == null) && (other.root == null); + return conf.update( + description: "${conf.description} -spawnUri-> ${other.description}", + main: "spawnUriMain", + newArgs: [ + other.mainFile, + other.config ?? "-", + other.root ?? "-", + "$search" + ], + expect: other.expect); + }; +} + +/// Convert command line parameters to file paths. +/// +/// This only works on the command line, not with `spawnUri`. +Configuration asPath(Configuration conf) { + bool change = false; + + String toPath(String string) { + if (string == null) return null; + if (string.startsWith("file:")) { + change = true; + return new File.fromUri(Uri.parse(string)).path; + } + return string; + } + + var mainFile = toPath(conf.mainFile); + var root = toPath(conf.root); + var config = toPath(conf.config); + if (!change) return null; + return conf.update( + description: conf.description + "/as path", + mainFile: mainFile, + root: root, + config: config); +} + +/// -------------------------------------------------------------- + +Future setUp() async { + fileRoot = createTempDir(); + // print("FILES: $fileRoot"); + httpServer = await startServer(httpFiles); + // print("HTTPS: ${httpServer.address.address}:${httpServer.port}"); + createConfigurations(); +} + +Future tearDown() async { + fileRoot.deleteSync(recursive: true); + await httpServer.close(); +} + +typedef Configuration ConfigurationTransformer(Configuration conf); + +Future runTests([List transformations]) async { + outer: + for (var config in configurations) { + if (transformations != null) { + for (int i = transformations.length - 1; i >= 0; i--) { + config = transformations[i](config); + if (config == null) { + continue outer; // Can be used to skip some tests. + } + } + } + await testConfiguration(config); + } +} + +// Creates a combination of configurations for running the Dart VM. +// +// The combinations covers most configurations of implicit and explicit +// package configurations over both file: and http: file sources. +// It also specifies the expected values of the following for a VM +// run in that configuration. +// +// * `Process.packageRoot` +// * `Process.packageConfig` +// * `Isolate.packageRoot` +// * `Isolate.packageRoot` +// * `Isolate.resolvePackageUri` of various inputs. +// * A variable defined in a library loaded using a `package:` URI. +// +// The configurations all have URIs as `root`, `config` and `mainFile` strings, +// have empty argument lists and `mainFile` points to the `main.dart` file. +void createConfigurations() { + add(String description, String mainDir, + {String root, String config, Map file, Map http, Map expect}) { + var id = freshName("conf"); + + file ??= {}; + http ??= {}; + + // Fix-up paths. + String fileUri = fileRoot.uri.resolve("$id/").toString(); + String httpUri = + "http://${httpServer.address.address}:${httpServer.port}/$id/"; + + String fixPath(String path) { + return path?.replaceAllMapped(fileHttpRegexp, (match) { + if (path.startsWith("%file/", match.start)) return fileUri; + return httpUri; + }); + } + + void fixPaths(Map dirs) { + for (var name in dirs.keys) { + var value = dirs[name]; + if (value is Map) { + Map subDir = value; + fixPaths(subDir); + } else { + var newValue = fixPath(value); + if (newValue != value) dirs[name] = newValue; + } + } + } + + if (!mainDir.endsWith("/")) mainDir += "/"; + // Insert main files into the main-dir map. + Map mainDirMap; + { + if (mainDir.startsWith("%file/")) { + mainDirMap = file; + } else { + mainDirMap = http; + } + var parts = mainDir.split('/'); + for (int i = 1; i < parts.length - 1; i++) { + var dirName = parts[i]; + mainDirMap = mainDirMap[dirName] ?? (mainDirMap[dirName] = {}); + } + } + + mainDirMap["main"] = testMain; + mainDirMap["spawnMain"] = spawnMain.replaceAll("%mainDir/", mainDir); + mainDirMap["spawnUriMain"] = spawnUriMain; + + mainDir = fixPath(mainDir); + root = fixPath(root); + config = fixPath(config); + fixPaths(file); + fixPaths(http); + // These expectations are default. If not overridden the value will be + // expected to be null. That is, you can't avoid testing the actual + // value of these, you can only change what value to expect. + // For values not included here (commented out), the result is not tested + // unless a value (maybe null) is provided. + fixPaths(expect); + + expect = { + "pconf": null, + "proot": null, + "iconf": null, + "iroot": null, + "foo": null, + "foo/": null, + "foo/bar": null, + "foo.x": "qux", + "bar/bar": null, + "relative": "relative/path", + "nonpkg": "http://example.org/file" + }..addAll(expect ?? const {}); + + // Add http files to the http server. + if (http.isNotEmpty) { + httpFiles[id] = http; + } + // Add file files to the file system. + if (file.isNotEmpty) { + createFiles(fileRoot, id, file); + } + + configurations.add(new Configuration( + description: description, + root: root, + config: config, + mainFile: mainDir + "main.dart", + args: const [], + expect: expect)); + } + + // The `test` function can generate file or http resources. + // It replaces "%file/" with URI of the root directory of generated files and + // "%http/" with the URI of the HTTP server's root in appropriate contexts + // (all file contents and parameters). + + // Tests that only use one scheme to access files. + for (var scheme in ["file", "http"]) { + /// Run a test in the current scheme. + /// + /// The files are served either through HTTP or in a local directory. + /// Use "%$scheme/" to refer to the root of the served files. + addScheme(description, main, {expect, files, args, root, config}) { + add("$scheme/$description", main, + expect: expect, + root: root, + config: config, + file: (scheme == "file") ? files : null, + http: (scheme == "http") ? files : null); + } + + { + // No parameters, no .packages files or packages/ dir. + // A "file:" source realizes there is no configuration and can't resolve + // any packages, but a "http:" source assumes a "packages/" directory. + addScheme("no resolution", "%$scheme/", + files: {}, + expect: (scheme == "file") + ? {"foo.x": null} + : { + "iroot": "%http/packages/", + "foo": "%http/packages/foo", + "foo/": "%http/packages/foo/", + "foo/bar": "%http/packages/foo/bar", + "foo.x": null, + "bar/bar": "%http/packages/bar/bar", + }); + } + + { + // No parameters, no .packages files, + // packages/ dir exists and is detected. + var files = {"packages": fooPackage}; + addScheme("implicit packages dir", "%$scheme/", files: files, expect: { + "iroot": "%$scheme/packages/", + "foo": "%$scheme/packages/foo", + "foo/": "%$scheme/packages/foo/", + "foo/bar": "%$scheme/packages/foo/bar", + "bar/bar": "%$scheme/packages/bar/bar", + }); + } + + { + // No parameters, no .packages files in current dir, but one in parent, + // packages/ dir exists and is used. + // + // Should not detect the .packages file in parent directory. + // That file is empty, so if it is used, the system cannot resolve "foo". + var files = { + "sub": {"packages": fooPackage}, + ".packages": "" + }; + addScheme( + "implicit packages dir overrides parent .packages", "%$scheme/sub/", + files: files, + expect: { + "iroot": "%$scheme/sub/packages/", + "foo": "%$scheme/sub/packages/foo", + "foo/": "%$scheme/sub/packages/foo/", + "foo/bar": "%$scheme/sub/packages/foo/bar", + // "foo.x": "qux", // Blocked by issue http://dartbug.com/26482 + "bar/bar": "%$scheme/sub/packages/bar/bar", + }); + } + + { + // No parameters, a .packages file next to entry is found and used. + // A packages/ directory is ignored. + var files = { + ".packages": "foo:pkgs/foo/", + "packages": {}, + "pkgs": fooPackage + }; + addScheme("implicit .packages file", "%$scheme/", files: files, expect: { + "iconf": "%$scheme/.packages", + "foo/": "%$scheme/pkgs/foo/", + "foo/bar": "%$scheme/pkgs/foo/bar", + }); + } + + { + // No parameters, a .packages file in parent dir, no packages/ dir. + // With a file: URI, find the .packages file. + // WIth a http: URI, assume a packages/ dir. + var files = {"sub": {}, ".packages": "foo:pkgs/foo/", "pkgs": fooPackage}; + addScheme(".packages file in parent", "%$scheme/sub/", + files: files, + expect: (scheme == "file") + ? { + "iconf": "%file/.packages", + "foo/": "%file/pkgs/foo/", + "foo/bar": "%file/pkgs/foo/bar", + } + : { + "iroot": "%http/sub/packages/", + "foo": "%http/sub/packages/foo", + "foo/": "%http/sub/packages/foo/", + "foo/bar": "%http/sub/packages/foo/bar", + "foo.x": null, + "bar/bar": "%http/sub/packages/bar/bar", + }); + } + + { + // Specified package root that doesn't exist. + // Ignores existing .packages file and packages/ dir. + addScheme("explicit root not there", "%$scheme/", + files: { + "packages": fooPackage, + ".packages": "foo:%$scheme/packages/" + }, + root: "%$scheme/notthere/", + expect: { + "proot": "%$scheme/notthere/", + "iroot": "%$scheme/notthere/", + "foo": "%$scheme/notthere/foo", + "foo/": "%$scheme/notthere/foo/", + "foo/bar": "%$scheme/notthere/foo/bar", + "foo.x": null, + "bar/bar": "%$scheme/notthere/bar/bar", + }); + } + + { + // Specified package config that doesn't exist. + // Ignores existing .packages file and packages/ dir. + addScheme("explicit config not there", "%$scheme/", + files: {".packages": "foo:packages/foo/", "packages": fooPackage}, + config: "%$scheme/.notthere", + expect: { + "pconf": "%$scheme/.notthere", + "iconf": null, // <- Only there if actually loaded (unspecified). + "foo/": null, + "foo/bar": null, + "foo.x": null, + }); + } + + { + // Specified package root with no trailing slash. + // The Platform.packageRoot and Isolate.packageRoot has a trailing slash. + var files = { + ".packages": "foo:packages/foo/", + "packages": {}, + "pkgs": fooPackage + }; + addScheme("explicit package root, no slash", "%$scheme/", + files: files, + root: "%$scheme/pkgs", + expect: { + "proot": "%$scheme/pkgs/", + "iroot": "%$scheme/pkgs/", + "foo": "%$scheme/pkgs/foo", + "foo/": "%$scheme/pkgs/foo/", + "foo/bar": "%$scheme/pkgs/foo/bar", + "bar/bar": "%$scheme/pkgs/bar/bar", + }); + } + + { + // Specified package root with trailing slash. + var files = { + ".packages": "foo:packages/foo/", + "packages": {}, + "pkgs": fooPackage + }; + addScheme("explicit package root, slash", "%$scheme/", + files: files, + root: "%$scheme/pkgs", + expect: { + "proot": "%$scheme/pkgs/", + "iroot": "%$scheme/pkgs/", + "foo": "%$scheme/pkgs/foo", + "foo/": "%$scheme/pkgs/foo/", + "foo/bar": "%$scheme/pkgs/foo/bar", + "bar/bar": "%$scheme/pkgs/bar/bar", + }); + } + + { + // Specified package config. + var files = { + ".packages": "foo:packages/foo/", + "packages": {}, + ".pkgs": "foo:pkgs/foo/", + "pkgs": fooPackage + }; + addScheme("explicit package config file", "%$scheme/", + files: files, + config: "%$scheme/.pkgs", + expect: { + "pconf": "%$scheme/.pkgs", + "iconf": "%$scheme/.pkgs", + "foo/": "%$scheme/pkgs/foo/", + "foo/bar": "%$scheme/pkgs/foo/bar", + }); + } + + { + // Specified package config as data: URI. + // The package config can be specified as a data: URI. + // (In that case, relative URI references in the config file won't work). + var files = { + ".packages": "foo:packages/foo/", + "packages": {}, + "pkgs": fooPackage + }; + var dataUri = "data:,foo:%$scheme/pkgs/foo/\n"; + addScheme("explicit data: config file", "%$scheme/", + files: files, + config: dataUri, + expect: { + "pconf": dataUri, + "iconf": dataUri, + "foo/": "%$scheme/pkgs/foo/", + "foo/bar": "%$scheme/pkgs/foo/bar", + }); + } + } + + // Tests where there are files on both http: and file: sources. + + for (var entryScheme in const ["file", "http"]) { + for (var pkgScheme in const ["file", "http"]) { + // Package root. + if (entryScheme != pkgScheme) { + // Package dir and entry point on different schemes. + var files = {}; + var https = {}; + (entryScheme == "file" ? files : https)["main"] = testMain; + (pkgScheme == "file" ? files : https)["pkgs"] = fooPackage; + add("$pkgScheme pkg/$entryScheme main", "%$entryScheme/", + file: files, + http: https, + root: "%$pkgScheme/pkgs/", + expect: { + "proot": "%$pkgScheme/pkgs/", + "iroot": "%$pkgScheme/pkgs/", + "foo": "%$pkgScheme/pkgs/foo", + "foo/": "%$pkgScheme/pkgs/foo/", + "foo/bar": "%$pkgScheme/pkgs/foo/bar", + "bar/bar": "%$pkgScheme/pkgs/bar/bar", + "foo.x": "qux", + }); + } + // Package config. The configuration file may also be on either source. + for (var configScheme in const ["file", "http"]) { + // Don't do the boring stuff! + if (entryScheme == configScheme && entryScheme == pkgScheme) continue; + // Package config, packages and entry point not all on same scheme. + var files = {}; + var https = {}; + (entryScheme == "file" ? files : https)["main"] = testMain; + (configScheme == "file" ? files : https)[".pkgs"] = + "foo:%$pkgScheme/pkgs/foo/\n"; + (pkgScheme == "file" ? files : https)["pkgs"] = fooPackage; + add("$pkgScheme pkg/$configScheme config/$entryScheme main", + "%$entryScheme/", + file: files, + http: https, + config: "%$configScheme/.pkgs", + expect: { + "pconf": "%$configScheme/.pkgs", + "iconf": "%$configScheme/.pkgs", + "foo/": "%$pkgScheme/pkgs/foo/", + "foo/bar": "%$pkgScheme/pkgs/foo/bar", + "foo.x": "qux", + }); + } + } + } +} + +// --------------------------------------------------------- +// Helper functionality. + +var fileHttpRegexp = new RegExp(r"%(?:file|http)/"); + +// Executes a test in a configuration. +// +// The test must specify which main file to use +// (`main`, `spawnMain` or `spawnUriMain`) +// and any arguments which will be used by `spawnMain` and `spawnUriMain`. +// +// The [expect] map may be used to override the expectations of the +// configuration on a value-by-value basis. Passing, e.g., `{"pconf": null}` +// will override only the `pconf` (`Platform.packageConfig`) expectation. +Future testConfiguration(Configuration conf) async { + print("-- ${conf.description}"); + var description = conf.description; + try { + var output = await execDart(conf.mainFile, + root: conf.root, config: conf.config, scriptArgs: conf.args); + match(json.decode(output), conf.expect, description, output); + } catch (e, s) { + // Unexpected error calling execDart or parsing the result. + // Report it and continue. + print("ERROR running $description: $e\n$s"); + failingTests.putIfAbsent(description, () => []).add("$e"); + } +} + +/// Test that the output of running testMain matches the expectations. +/// +/// The output is a string which is parse as a JSON literal. +/// The resulting map is always mapping strings to strings, or possibly `null`. +/// The expectations can have non-string values other than null, +/// they are `toString`'ed before being compared (so the caller can use a URI +/// or a File/Directory directly as an expectation). +void match(Map actuals, Map expectations, String desc, String actualJson) { + for (var key in expectations.keys) { + var expectation = expectations[key]?.toString(); + var actual = actuals[key]; + if (expectation != actual) { + print("ERROR: $desc: $key: Expected: <$expectation> Found: <$actual>"); + failingTests + .putIfAbsent(desc, () => []) + .add("$key: $expectation != $actual"); + } + } +} + +const String improt = "import"; // Avoid multitest import rewriting. + +/// Script that prints the current state and the result of resolving +/// a few package URIs. This script will be invoked in different settings, +/// and the result will be parsed and compared to the expectations. +const String testMain = """ +$improt "dart:convert" show json; +$improt "dart:io" show Platform, Directory; +$improt "dart:isolate" show Isolate; +$improt "package:foo/foo.dart" deferred as foo; +main(_) async { + String platformRoot = await Platform.packageRoot; + String platformConfig = await Platform.packageConfig; + Directory cwd = Directory.current; + Uri script = Platform.script; + Uri isolateRoot = await Isolate.packageRoot; + Uri isolateConfig = await Isolate.packageConfig; + Uri base = Uri.base; + Uri res1 = await Isolate.resolvePackageUri(Uri.parse("package:foo")); + Uri res2 = await Isolate.resolvePackageUri(Uri.parse("package:foo/")); + Uri res3 = await Isolate.resolvePackageUri(Uri.parse("package:foo/bar")); + Uri res4 = await Isolate.resolvePackageUri(Uri.parse("package:bar/bar")); + Uri res5 = await Isolate.resolvePackageUri(Uri.parse("relative/path")); + Uri res6 = await Isolate.resolvePackageUri( + Uri.parse("http://example.org/file")); + String fooX = await foo + .loadLibrary() + .timeout(const Duration(seconds: 1)) + .then((_) => foo.x, onError: (_) => null); + print(json.encode({ + "cwd": cwd.path, + "base": base?.toString(), + "script": script?.toString(), + "proot": platformRoot, + "pconf": platformConfig, + "iroot" : isolateRoot?.toString(), + "iconf" : isolateConfig?.toString(), + "foo": res1?.toString(), + "foo/": res2?.toString(), + "foo/bar": res3?.toString(), + "foo.x": fooX?.toString(), + "bar/bar": res4?.toString(), + "relative": res5?.toString(), + "nonpkg": res6?.toString(), + })); +} +"""; + +/// Script that spawns a new Isolate using Isolate.spawnUri. +/// +/// Takes URI of target isolate, package config, package root and +/// automatic package resolution-flag parameters as command line arguments. +/// Any further arguments are forwarded to the spawned isolate. +const String spawnUriMain = """ +$improt "dart:isolate"; +$improt "dart:async"; +main(args) async { + Uri target = Uri.parse(args[0]); + Uri config = (args[1] == "-") ? null : Uri.parse(args[1]); + Uri root = (args[2] == "-") ? null : Uri.parse(args[2]); + bool search = args[3] == "true"; + var restArgs = args.skip(4).toList(); + // Port keeps isolate alive until spawned isolate terminates. + var port = new RawReceivePort(); + port.handler = (res) async { + port.close(); // Close on exit or first error. + if (res != null) { + await new Future.error(res[0], new StackTrace.fromString(res[1])); + } + }; + Isolate.spawnUri(target, restArgs, null, + packageRoot: root, packageConfig: config, + automaticPackageResolution: search, + onError: port.sendPort, onExit: port.sendPort); +} +"""; + +/// Script that spawns a new Isolate using Isolate.spawn. +/// +/// Uses the first argument to select which target to spawn. +/// Should be either "test", "uri" or "spawn". +const String spawnMain = """ +$improt "dart:async"; +$improt "dart:isolate"; +$improt "%mainDir/main.dart" as test; +$improt "%mainDir/spawnUriMain.dart" as spawnUri; +main(List args) async { + // Port keeps isolate alive until spawned isolate terminates. + var port = new RawReceivePort(); + port.handler = (res) async { + port.close(); // Close on exit or first error. + if (res != null) { + await new Future.error(res[0], new StackTrace.fromString(res[1])); + } + }; + var arg = args.first; + var rest = args.skip(1).toList(); + var target; + if (arg == "main") { + target = test.main; + } else if (arg == "spawnUriMain") { + target = spawnUri.main; + } else { + target = main; + } + Isolate.spawn(target, rest, onError: port.sendPort, onExit: port.sendPort); +} +"""; + +/// A package directory containing only one package, "foo", with one file. +const Map fooPackage = const { + "foo": const {"foo": "var x = 'qux';"} +}; + +/// Runs the Dart executable with the provided parameters. +/// +/// Captures and returns the output. +Future execDart(String script, + {String root, String config, Iterable scriptArgs}) async { + var checked = false; + assert((checked = true)); + // TODO: Find a way to change CWD before running script. + var executable = Platform.executable; + var args = []; + if (checked) args.add("--checked"); + if (root != null) args.add("--package-root=$root"); + if (config != null) args.add("--packages=$config"); + args.add(script); + if (scriptArgs != null) { + args.addAll(scriptArgs); + } + return Process.run(executable, args).then((results) { + if (results.exitCode != 0 || results.stderr.isNotEmpty) { + throw results.stderr; + } + return results.stdout; + }); +} + +/// Creates a number of files and subdirectories. +/// +/// The [content] is the content of the directory itself. The map keys are +/// names and the values are either strings that represent Dart file contents +/// or maps that represent subdirectories. +void createFiles(Directory tempDir, String subDir, Map content) { + Directory createDir(Directory base, String name) { + Directory newDir = new Directory(p.join(base.path, name)); + newDir.createSync(); + return newDir; + } + + void createTextFile(Directory base, String name, String content) { + File newFile = new File(p.join(base.path, name)); + newFile.writeAsStringSync(content); + } + + void createRecursive(Directory dir, Map map) { + for (var name in map.keys) { + var content = map[name]; + if (content is String) { + // If the name starts with "." it's a .packages file, otherwise it's + // a dart file. Those are the only files we care about in this test. + createTextFile( + dir, name.startsWith(".") ? name : name + ".dart", content); + } else { + assert(content is Map); + var subdir = createDir(dir, name); + createRecursive(subdir, content); + } + } + } + + createRecursive(createDir(tempDir, subDir), content); +} + +/// Start an HTTP server which serves a directory/file structure. +/// +/// The directories and files are described by [files]. +/// +/// Each map key is an entry in a directory. A `Map` value is a sub-directory +/// and a `String` value is a text file. +/// The file contents are run through [fixPaths] to allow them to be self- +/// referential. +Future startServer(Map files) async { + return (await HttpServer.bind(InternetAddress.loopbackIPv4, 0)) + ..forEach((request) { + var result = files; + onFailure: + { + for (var part in request.uri.pathSegments) { + if (part.endsWith(".dart")) { + part = part.substring(0, part.length - 5); + } + if (result is Map) { + result = result[part]; + } else { + break onFailure; + } + } + if (result is String) { + request.response + ..write(result) + ..close(); + return; + } + } + request.response + ..statusCode = HttpStatus.notFound + ..close(); + }); +} + +// Counter used to avoid reusing temporary file or directory names. +// +// Used when adding extra files to an existing directory structure, +// and when creating temporary directories. +// +// Some platform temporary-directory implementations are timer based, +// and creating two temp-dirs withing a short duration may cause a collision. +int tmpNameCounter = 0; + +// Fresh file name. +String freshName([String base = "tmp"]) => "$base${tmpNameCounter++}"; + +Directory createTempDir() { + return Directory.systemTemp.createTempSync(freshName("pftest-")); +} + +typedef void ConfigUpdate(Configuration configuration); + +/// The configuration for a single test. +class Configuration { + /// The "description" of the test - a description of the set-up. + final String description; + + /// The package root parameter passed to the Dart isolate. + /// + /// At most one of [root] and [config] should be supplied. If both are + /// omitted, a VM will search for a packages file or dir. + final String root; + + /// The package configuration file location passed to the Dart isolate. + final String config; + + /// Path to the main file to run. + final String mainFile; + + /// List of arguments to pass to the main function. + final List args; + + /// The expected values for `Platform.package{Root,Config}`, + /// `Isolate.package{Root,Config}` and resolution of package URIs + /// in a `foo` package. + /// + /// The results are found by running the `main.dart` file inside [mainDir]. + /// The tests can run this file after doing other `spawn` or `spawnUri` calls. + final Map expect; + + Configuration( + {this.description, + this.root, + this.config, + this.mainFile, + this.args, + this.expect}); + + // Gets the type of main file, one of `main`, `spawnMain` or `spawnUriMain`. + String get mainType { + var lastSlash = mainFile.lastIndexOf("/"); + if (lastSlash < 0) { + // Assume it's a Windows path. + lastSlash = mainFile.lastIndexOf(r"\"); + } + var name = mainFile.substring(lastSlash + 1, mainFile.length - 5); + assert(name == "main" || name == "spawnMain" || name == "spawnUriMain"); + return name; + } + + String get mainPath { + var lastSlash = mainFile.lastIndexOf("/"); + if (lastSlash < 0) { + // Assume it's a Windows path. + lastSlash = mainFile.lastIndexOf(r"\"); + } + return mainFile.substring(0, lastSlash + 1); + } + + /// Create a new configuration from the old one. + /// + /// [description] is new description. + /// + /// [main] is one of `main`, `spawnMain` or `spawnUriMain`, and changes + /// the [Configuration.mainFile] to a different file in the same directory. + /// + /// [mainFile] overrides [Configuration.mainFile] completely, and ignores + /// [main]. + /// + /// [newArgs] are prepended to the existing [Configuration.args]. + /// + /// [args] overrides [Configuration.args] completely and ignores [newArgs]. + /// + /// [expect] overrides individual expectations. + /// + /// [root] and [config] overrides the existing values. + Configuration update( + {String description, + String main, + String mainFile, + String root, + String config, + List args, + List newArgs, + Map expect}) { + return new Configuration( + description: description ?? this.description, + root: root ?? this.root, + config: config ?? this.config, + mainFile: mainFile ?? + ((main == null) ? this.mainFile : "${this.mainPath}$main.dart"), + args: args ?? + ([] + ..addAll(newArgs ?? const []) + ..addAll(this.args)), + expect: expect == null ? this.expect : new Map.from(this.expect) + ..addAll(expect ?? const {})); + } + + // For debugging. + String toString() { + return "Configuration($description\n" + " root : $root\n" + " config: $config\n" + " main : $mainFile\n" + " args : ${args.map((x) => '"$x"').join(" ")}\n" + ") : expect {\n${expect.keys.map((k) => + ' "$k"'.padRight(6) + ":${json.encode(expect[k])}\n").join()}" + "}"; + } +} + +// Inserts the file with generalized [name] at [path] with [content]. +// +// The [path] is a directory where the file is created. It must start with +// either '%file/' or '%http/' to select the structure to put it into. +// +// The [name] should not have a trailing ".dart" for Dart files. Any file +// not starting with "." is assumed to be a ".dart" file. +void insertFileAt( + Map file, Map http, String path, String name, String content) { + var parts = path.split('/').toList(); + var dir = (parts[0] == "%file") ? file : http; + for (var i = 1; i < parts.length - 1; i++) { + var entry = parts[i]; + dir = dir[entry] ?? (dir[entry] = {}); + } + dir[name] = content; +} diff --git a/tests/standalone/pair_location_remapping_test.dart b/tests/standalone/pair_location_remapping_test.dart new file mode 100644 index 00000000000..13bf7f90658 --- /dev/null +++ b/tests/standalone/pair_location_remapping_test.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test that pair locations are remaped in slow path environments. +// VMOptions=--optimization_counter_threshold=10 --no-use-osr --no-background_compilation + +import "package:expect/expect.dart"; + +class A { + final f; + A(this.f); +} + +foo(int i) { + int j = 0x7fffffffffffffff + i; + var c = new A(j); // allocation will be sunk + var r = 0; + for (var k = 0; k < 10; k++) { + if ((j & (1 << k)) != 0) { + r++; + } + } + return c.f - r; +} + +main() { + for (var i = 0; i < 1000; i++) { + Expect.equals(0x7fffffffffffffff - 10, foo(0)); + } +} diff --git a/tests/standalone/pow_test.dart b/tests/standalone/pow_test.dart new file mode 100644 index 00000000000..2d6a8e29f01 --- /dev/null +++ b/tests/standalone/pow_test.dart @@ -0,0 +1,97 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart test program for testing math's pow. + +library pow_test; + +import "package:expect/expect.dart"; +import 'dart:math'; + +var expectedResults = [ + 1, + 2, + 4, + 8, + 16, + 32, + 64, + 128, + 256, + 512, + 1024, + 2048, + 4096, + 8192, + 16384, + 32768, + 65536, + 131072, + 262144, + 524288, + 1048576, + 2097152, + 4194304, + 8388608, + 16777216, + 33554432, + 67108864, + 134217728, + 268435456, + 536870912, + 1073741824, + 2147483648, + 4294967296, + 8589934592, + 17179869184, + 34359738368, + 68719476736, + 137438953472, + 274877906944, + 549755813888, + 1099511627776, + 2199023255552, + 4398046511104, + 8796093022208, + 17592186044416, + 35184372088832, + 70368744177664, + 140737488355328, + 281474976710656, + 562949953421312, + 1125899906842624, + 2251799813685248, + 4503599627370496, + 9007199254740992, + 18014398509481984, + 36028797018963968, + 72057594037927936, + 144115188075855872, + 288230376151711744, + 576460752303423488, + 1152921504606846976, + 2305843009213693952, + 4611686018427387904, +]; + +void main() { + int exp = 0; + for (int val in expectedResults) { + Expect.equals(val, pow(2, exp)); + Expect.equals(val.toDouble(), pow(2, exp.toDouble())); + exp++; + } + + // Optimize it. + for (int i = 0; i < 8888; i++) { + pow(2, 3); + pow(2.0, 3.0); + } + exp = 0; + for (int val in expectedResults) { + Expect.equals(val, pow(2, exp)); + Expect.equals(val.toDouble(), pow(2, exp.toDouble())); + exp++; + } +} diff --git a/tests/standalone/priority_queue_stress_test.dart b/tests/standalone/priority_queue_stress_test.dart new file mode 100644 index 00000000000..4f70334a438 --- /dev/null +++ b/tests/standalone/priority_queue_stress_test.dart @@ -0,0 +1,327 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library priority_queue; + +import 'dart:collection'; +import 'dart:math'; + +/** + * A priority used for the priority queue. Subclasses only need to implement + * the compareTo function. + */ +abstract class Priority implements Comparable { + /** + * Return < 0 if other is bigger, >0 if other is smaller, 0 if they are equal. + */ + int compareTo(dynamic other); + bool operator <(dynamic other) => compareTo(other) < 0; + bool operator >(dynamic other) => compareTo(other) > 0; + bool operator ==(dynamic other) => compareTo(other) == 0; +} + +/** + * Priority based on integers. + */ +class IntPriority extends Priority { + int priority; + IntPriority(int this.priority); + + int compareTo(dynamic other) { + return (priority - other.priority) as int; + } + + String toString() => "$priority"; +} + +/** + * An element of a priority queue. The type is used restriction based + * querying of the queues. + */ +abstract class TypedElement { + bool typeEquals(var other); +} + +class StringTypedElement extends TypedElement { + String type; + V value; + StringTypedElement(String this.type, V this.value); + bool typeEquals(dynamic otherType) => otherType == type; + String toString() => ""; +} + +/** + * A priority node in a priority queue. A priority node contains all of the + * values for a given priority in a given queue. It is part of a linked + * list of nodes, with prev and next pointers. + */ +class PriorityNode { + T priority; + Queue values; + PriorityNode? prev; + PriorityNode? next; + PriorityNode(N initialNode, T this.priority) : values = new Queue() { + add(initialNode); + } + + void add(N n) => values.add(n); + + bool remove(N n) => values.remove(n); + + N removeFirst() => values.removeFirst(); + + bool get isEmpty => values.isEmpty; + + N get first => values.first; + + String toString() => "Priority: $priority $values"; +} + +/** + * A priority queue with a FIFO property for nodes with same priority. + * The queue guarantees that nodes are returned in the same order they + * are added for a given priority. + * For type safety this queue is guarded by the elements being subclasses of + * TypedElement - this is not strictly neccesary since we never actually + * use the value or type of the nodes. + */ +class PriorityQueue { + PriorityNode? head; + int length = 0; + + void add(N value, P priority) { + length++; + if (head == null) { + head = new PriorityNode(value, priority); + return; + } + assert(head!.next == null); + var node = head!; + while (node.prev != null && node.priority > priority) { + node = node.prev as PriorityNode; + } + if (node.priority == priority) { + node.add(value); + } else if (node.priority < priority) { + var newNode = new PriorityNode(value, priority); + newNode.next = node.next; + if (node.next != null) node.next!.prev = newNode; + newNode.prev = node; + node.next = newNode; + if (node == head) head = newNode; + } else { + var newNode = new PriorityNode(value, priority); + node.prev = newNode; + newNode.next = node; + } + } + + N get first => head!.first; + + Priority get firstPriority => head!.priority; + + bool get isEmpty => head == null; + + N removeFirst() { + if (isEmpty) throw "Can't get element from empty queue"; + var value = head!.removeFirst(); + if (head!.isEmpty) { + if (head!.prev != null) { + head!.prev!.next = null; + } + head = head!.prev as PriorityNode?; + } + length--; + assert(head == null || head!.next == null); + return value; + } + + String toString() { + if (head == null) return "Empty priority queue"; + var node = head!; + var buffer = new StringBuffer(); + while (node.prev != null) { + buffer.writeln(node); + node = node.prev as PriorityNode; + } + buffer.writeln(node); + return buffer.toString(); + } +} + +/** + * Implements a specialized priority queue that efficiently allows getting + * the highest priorized node that adheres to a set of restrictions. + * Most notably it allows to get the highest priority node where the node's + * type is not in an exclude list. + * In addition, the queue has a number of properties: + * The queue has fifo semantics for nodes with the same priority and type, + * i.e., if nodes a and b are added to the queue with priority x and type z + * then a is returned first iff a was added before b + * For different types with the same priority no guarantees are given, but + * the returned values try to be fair by returning from the biggest list of + * tasks in case of priority clash. (This could be fixed by adding timestamps + * to every node, that is _only_ used when collisions occur, not for + * insertions) + */ +class RestrictViewPriorityQueue { + // We can't use the basic dart priority queue since it does not guarantee + // FIFO for items with the same order. This is currently not uptimized for + // different N, if many different N is expected here we should have a + // priority queue instead of a list. + List> restrictedQueues = >[]; + PriorityQueue mainQueue = new PriorityQueue(); + + void add(N value, P priority) { + for (var queue in restrictedQueues) { + if ((queue.first as StringTypedElement).value == value) { + queue.add(value, priority); + } + } + mainQueue.add(value, priority); + } + + bool get isEmpty => restrictedQueues.length + mainQueue.length == 0; + + int get length => + restrictedQueues.fold(0, (v, e) => v + e.length) + mainQueue.length; + + PriorityQueue? getRestricted(List restrictions) { + var current = null; + // Find highest restricted priority. + for (var queue in restrictedQueues) { + if (!restrictions.any((e) => queue.head!.first.typeEquals(e))) { + if (current == null || queue.firstPriority > current.firstPriority) { + current = queue; + } else if (current.firstPriority == queue.firstPriority) { + current = queue.length > current.length ? queue : current; + } + } + } + return current; + } + + N? get first { + if (isEmpty) throw "Trying to remove node from empty queue"; + var candidate = getRestricted([]); + if (candidate != null && + (mainQueue.isEmpty || + mainQueue.firstPriority < candidate.firstPriority)) { + return candidate.first as N; + } + return mainQueue.isEmpty ? null : mainQueue.first; + } + + /** + * Returns the node that under the given set of restrictions. + * If the queue is empty this function throws. + * If the queue is not empty, but no node exists that adheres to the + * restrictions we return null. + */ + N? removeFirst({List restrictions: const []}) { + if (isEmpty) throw "Trying to remove node from empty queue"; + var candidate = getRestricted(restrictions); + + if (candidate != null && + (mainQueue.isEmpty || + mainQueue.firstPriority < candidate.firstPriority)) { + var value = candidate.removeFirst(); + if (candidate.isEmpty) restrictedQueues.remove(candidate); + return value as N; + } + while (!mainQueue.isEmpty) { + var currentPriority = mainQueue.firstPriority; + var current = mainQueue.removeFirst(); + if (!restrictions.any((e) => current.typeEquals(e))) { + return current; + } else { + PriorityQueue? restrictedQueue; + for (var e in restrictedQueues) { + if (current.typeEquals((e.first as StringTypedElement).type)) { + restrictedQueue = e; + break; + } + } + if (restrictedQueue == null) { + restrictedQueue = new PriorityQueue(); + restrictedQueues.add(restrictedQueue); + } + restrictedQueue.add(current, currentPriority as P); + } + } + return null; + } + + String toString() { + if (isEmpty) return "Empty queue"; + var buffer = new StringBuffer(); + if (!restrictedQueues.isEmpty) { + buffer.writeln("Restricted queues"); + for (var queue in restrictedQueues) { + buffer.writeln("$queue"); + } + } + buffer.writeln("Main queue:"); + buffer.writeln("$mainQueue"); + return buffer.toString(); + } +} + +/// TEMPORARY TESTING AND PERFORMANCE +void main([args]) { + stress(new RestrictViewPriorityQueue()); +} + +void stress(queue) { + final int SIZE = 50000; + Random random = new Random(29); + + var priorities = [1, 2, 3, 16, 32, 42, 56, 57, 59, 90]; + var values = [ + new StringTypedElement('safari', 'foo'), + new StringTypedElement('ie', 'bar'), + new StringTypedElement('ff', 'foobar'), + new StringTypedElement('dartium', 'barfoo'), + new StringTypedElement('chrome', 'hest'), + new StringTypedElement('drt', 'fisk') + ]; + + var restricted = [values[0], values[4]]; + + void addRandom() { + queue.add(values[random.nextInt(values.length)], + new IntPriority(priorities[random.nextInt(priorities.length)])); + } + + var stopwatch = new Stopwatch()..start(); + while (queue.length < SIZE) { + addRandom(); + } + + stopwatch.stop(); + print("Adding took: ${stopwatch.elapsedMilliseconds}"); + print("Queue length: ${queue.length}"); + + stopwatch = new Stopwatch()..start(); + while (queue.length > 0) { + queue.removeFirst(); + } + stopwatch.stop(); + print("Remowing took: ${stopwatch.elapsedMilliseconds}"); + print("Queue length: ${queue.length}"); + + print("Restricted add/remove"); + while (queue.length < SIZE) { + addRandom(); + } + + for (int i = 0; i < SIZE; i++) { + if (random.nextDouble() < 0.5) { + queue.removeFirst(restrictions: restricted); + } else { + queue.removeFirst(); + } + addRandom(); + } +} diff --git a/tests/standalone/regress31114_test.dart b/tests/standalone/regress31114_test.dart new file mode 100644 index 00000000000..2977a21c967 --- /dev/null +++ b/tests/standalone/regress31114_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// VMOptions=--background-compilation=false --optimization-counter-threshold=20 + +import 'pow_test.dart' as test; + +main() => test.main(); diff --git a/tests/standalone/regress_25335_test.dart b/tests/standalone/regress_25335_test.dart new file mode 100644 index 00000000000..500cc7f87b1 --- /dev/null +++ b/tests/standalone/regress_25335_test.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Test that canonicalization inserts constants with correct representation. +// VMOptions=--optimization-counter-threshold=10 --optimization-filter=bar --no-background-compilation + +import 'dart:typed_data'; + +toSigned(v, width) { + var signMask = 1 << (width - 1); + return (v & (signMask - 1)) - (v & signMask); +} + +foo(value) { + return value >> 32; +} + +bar(td) { + return toSigned(foo(td[0]), 64); +} + +main() { + toSigned(1 << 1, 32); + toSigned(1 << 32, 32); + + var l = new Int64List(1); + l[0] = 0x78f7f6f5f4f3f2f1; + + for (var i = 0; i < 20; i++) { + bar(l); + } +} diff --git a/tests/standalone/regress_26031_test.dart b/tests/standalone/regress_26031_test.dart new file mode 100644 index 00000000000..60dd89b4e6c --- /dev/null +++ b/tests/standalone/regress_26031_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--enable-isolate-groups +// VMOptions=--no-enable-isolate-groups + +import 'dart:io'; +import 'dart:isolate'; + +import "package:expect/expect.dart"; + +void checkResolvedExecutable(Object reObj) { + String re = reObj as String; + Expect.equals(Platform.resolvedExecutable, re); +} + +main() { + var exitPort = new ReceivePort(); + Isolate.spawn(checkResolvedExecutable, Platform.resolvedExecutable, + onExit: exitPort.sendPort); + exitPort.listen((_) => exitPort.close()); +} diff --git a/tests/standalone/regress_28854_1_test.dart b/tests/standalone/regress_28854_1_test.dart new file mode 100644 index 00000000000..30b304a002d --- /dev/null +++ b/tests/standalone/regress_28854_1_test.dart @@ -0,0 +1,44 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--enable-isolate-groups +// VMOptions=--no-enable-isolate-groups + +library regress; + +import 'dart:isolate'; + +abstract class N {} + +class J extends N { + final String s; + J(this.s); +} + +class K extends N { + final int i; + K(this.i); +} + +void isolate(Object portObj) { + SendPort port = portObj as SendPort; + port.send(N); + port.send(new J("8" * 4)); + for (int i = 0; i < 80000; i++) { + port.send(new K(i)); + } + port.send('done'); +} + +main() async { + var recv = new RawReceivePort(); + recv.handler = (k) { + if (k is J) print(k.s.length); + if (k is String) { + print(k); + recv.close(); + } + }; + var iso = await Isolate.spawn(isolate, recv.sendPort); +} diff --git a/tests/standalone/regress_28854_2_test.dart b/tests/standalone/regress_28854_2_test.dart new file mode 100644 index 00000000000..21395c13e24 --- /dev/null +++ b/tests/standalone/regress_28854_2_test.dart @@ -0,0 +1,43 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--enable-isolate-groups +// VMOptions=--no-enable-isolate-groups + +library regress; + +import 'dart:isolate'; + +abstract class N {} + +class J extends N { + final String s; + J(this.s); +} + +class K extends N { + final int i; + K(this.i); +} + +void isolate(Object portObj) { + SendPort port = portObj as SendPort; + port.send(new J("8" * 4)); + for (int i = 0; i < 80000; i++) { + port.send(new K(i)); + } + port.send('done'); +} + +main() async { + var recv = new RawReceivePort(); + recv.handler = (k) { + if (k is J) print(k.s.length); + if (k is String) { + print(k); + recv.close(); + } + }; + var iso = await Isolate.spawn(isolate, recv.sendPort); +} diff --git a/tests/standalone/regress_29350_test.dart b/tests/standalone/regress_29350_test.dart new file mode 100644 index 00000000000..fe3b5348321 --- /dev/null +++ b/tests/standalone/regress_29350_test.dart @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file + * for details. All rights reserved. Use of this source code is governed by a + * BSD-style license that can be found in the LICENSE file. + */ + +// 'covariant' when used incorrectly should report an error and not crash +// the VM. + +typedef bool Test(covariant num arg); //# none: compile-time error + +void main() { + Test t = (int value) => false; +} diff --git a/tests/standalone/regress_29695_test.dart b/tests/standalone/regress_29695_test.dart new file mode 100644 index 00000000000..2d8ae75e773 --- /dev/null +++ b/tests/standalone/regress_29695_test.dart @@ -0,0 +1,25 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Test that type tests are not misoptimized. +// VMOptions=--optimization-counter-threshold=1000 --optimization-filter=IsAnInt + +main() { + train(); + if (IsAnInt("This is not an int")) throw "oops"; +} + +// Prime the IC with things that are and are not ints. +void train() { + for (int i = 0; i < 10000; i++) { + IsAnInt(42); // Smi - always goes first in the generated code. + IsAnInt(1 << 62); // Mint on 64 bit platforms. + IsAnInt(1 << 62); + // This one that is not an int goes last in the IC because it is called + // less frequently. + IsAnInt(4.2); + } +} + +bool IsAnInt(f) => f is int; diff --git a/tests/standalone/regress_41329_absolute_test.dart b/tests/standalone/regress_41329_absolute_test.dart new file mode 100644 index 00000000000..cc2a40260bd --- /dev/null +++ b/tests/standalone/regress_41329_absolute_test.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:async_helper/async_helper.dart'; +import 'package:path/path.dart' as p; +import 'package:expect/expect.dart'; + +Future main() async { + final origDir = Directory.current; + final exePath = Platform.resolvedExecutable; + final d = Directory.systemTemp.createTempSync('dart_symlink'); + + // Roughly emulate a Brew installation: + // - $BREW/bin/dart -> ../Cellar/dart/2.8.0-dev.20.0/bin/dart + // - $BREW/Cellar/dart/2.8.0-dev.20.0/bin/dart -> $DART_SDK/bin/dart + final a = Directory('${d.path}/usr/local/bin'); + a.createSync(recursive: true); + + // /usr/local/Cellar/dart/2.8.0-dev.20.0/bin/dart -> $DART_SDK/bin/dart + Directory.current = a; + final linkLocation = '../Cellar/dart/2.8.0-dev.20.0/bin/dart'; + final link = Link(linkLocation); + link.createSync(exePath, recursive: true); + + // /usr/local/bin/dart -> /usr/local/Cellar/dart/2.8.0-dev.20/bin/dart + final link2 = Link('dart')..createSync(linkLocation, recursive: true); + final path = Uri.parse(link2.absolute.path).path; + Directory.current = origDir; + final result = await Process.run('${path}', ['help']); + Expect.equals(result.exitCode, 0); +} diff --git a/tests/standalone/regress_41329_relative_test.dart b/tests/standalone/regress_41329_relative_test.dart new file mode 100644 index 00000000000..cc2a40260bd --- /dev/null +++ b/tests/standalone/regress_41329_relative_test.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:async_helper/async_helper.dart'; +import 'package:path/path.dart' as p; +import 'package:expect/expect.dart'; + +Future main() async { + final origDir = Directory.current; + final exePath = Platform.resolvedExecutable; + final d = Directory.systemTemp.createTempSync('dart_symlink'); + + // Roughly emulate a Brew installation: + // - $BREW/bin/dart -> ../Cellar/dart/2.8.0-dev.20.0/bin/dart + // - $BREW/Cellar/dart/2.8.0-dev.20.0/bin/dart -> $DART_SDK/bin/dart + final a = Directory('${d.path}/usr/local/bin'); + a.createSync(recursive: true); + + // /usr/local/Cellar/dart/2.8.0-dev.20.0/bin/dart -> $DART_SDK/bin/dart + Directory.current = a; + final linkLocation = '../Cellar/dart/2.8.0-dev.20.0/bin/dart'; + final link = Link(linkLocation); + link.createSync(exePath, recursive: true); + + // /usr/local/bin/dart -> /usr/local/Cellar/dart/2.8.0-dev.20/bin/dart + final link2 = Link('dart')..createSync(linkLocation, recursive: true); + final path = Uri.parse(link2.absolute.path).path; + Directory.current = origDir; + final result = await Process.run('${path}', ['help']); + Expect.equals(result.exitCode, 0); +} diff --git a/tests/standalone/slowpath_safepoints_test.dart b/tests/standalone/slowpath_safepoints_test.dart new file mode 100644 index 00000000000..c983e623131 --- /dev/null +++ b/tests/standalone/slowpath_safepoints_test.dart @@ -0,0 +1,48 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test that safepoints associated with slowpaths don't mark non-existing values +// alive. +// VMOptions=--optimization-counter-threshold=5 --no-inline_alloc --no-background-compilation + +class C { + final next; + C(this.next); +} + +noop(a1, a2, a3, a4, a5, a6, a7, a8, a9) => 0; + +crash(f, i) { + final obj1 = new C(null); + final obj2 = new C(obj1); + final obj3 = new C(obj2); + final obj4 = new C(obj3); + final obj5 = new C(obj4); + final obj6 = new C(obj5); + final obj7 = new C(obj6); + final obj8 = new C(obj7); + final obj9 = new C(obj8); + + f(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9); + f(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9); + + final d1 = (i + 0).toDouble(); + final d2 = (i + 1).toDouble(); + final d3 = (i + 2).toDouble(); + final d4 = (i + 3).toDouble(); + final d5 = (i + 4).toDouble(); + final d6 = (i + 5).toDouble(); + final d7 = (i + 6).toDouble(); + final d8 = (i + 7).toDouble(); + final d9 = (i + 8).toDouble(); + + f(d1, d2, d3, d4, d5, d6, d7, d8, d9); + f(d1, d2, d3, d4, d5, d6, d7, d8, d9); +} + +main() { + for (var i = 0; i < 10; i++) { + print(i); + crash(noop, 10); + } +} diff --git a/tests/standalone/typed_array_int64_uint64_test.dart b/tests/standalone/typed_array_int64_uint64_test.dart new file mode 100644 index 00000000000..7b57986a462 --- /dev/null +++ b/tests/standalone/typed_array_int64_uint64_test.dart @@ -0,0 +1,97 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--enable-isolate-groups +// VMOptions=--no-enable-isolate-groups +// +// Dart test program for testing native typed arrays, int64 and uint64 only. + +// Library tag to be able to run in html test framework. +library TypedArray; + +import "package:expect/expect.dart"; +import 'package:async_helper/async_helper.dart'; +import 'dart:async'; +import 'dart:isolate'; +import 'dart:typed_data'; + +main() { + test(int64_receiver); + test(uint64_receiver); +} + +test(f) { + asyncStart(); + return f().whenComplete(asyncEnd); +} + +// Int64 array. +Int64List initInt64() { + var int64 = new Int64List(2); + int64[0] = 10000000; + int64[1] = 100000000; + return int64; +} + +Int64List int64 = initInt64(); + +int64_receiver() { + var response = new ReceivePort(); + var remote = Isolate.spawn(int64_sender, [int64.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(int64.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(int64[i], a[i]); + } + print("int64_receiver"); + asyncEnd(); + }); +} + +int64_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(int64.length, len); + var a = new Int64List(len); + for (int i = 0; i < len; i++) { + a[i] = int64[i]; + } + r.send(a); +} + +// Uint64 array. +Uint64List initUint64() { + var uint64 = new Uint64List(2); + uint64[0] = 0xffffffffffffffff; + uint64[1] = 0x7fffffffffffffff; + return uint64; +} + +Uint64List uint64 = initUint64(); + +uint64_receiver() { + var response = new ReceivePort(); + var remote = Isolate.spawn(uint64_sender, [uint64.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(uint64.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(uint64[i], a[i]); + } + print("uint64_receiver"); + asyncEnd(); + }); +} + +uint64_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(uint64.length, len); + var a = new Uint64List(len); + for (int i = 0; i < len; i++) { + a[i] = uint64[i]; + } + r.send(a); +} diff --git a/tests/standalone/typed_array_test.dart b/tests/standalone/typed_array_test.dart new file mode 100644 index 00000000000..6e4c6c3a108 --- /dev/null +++ b/tests/standalone/typed_array_test.dart @@ -0,0 +1,316 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--enable-isolate-groups +// VMOptions=--no-enable-isolate-groups +// +// Dart test program for testing native float and int arrays. 64-bit int arrays +// are in a separate test. + +// Library tag to be able to run in html test framework. +library TypedArray; + +import "package:expect/expect.dart"; +import 'package:async_helper/async_helper.dart'; +import 'dart:isolate'; +import 'dart:typed_data'; + +void main() { + test(int8_receiver); + test(uint8_receiver); + test(int16_receiver); + test(uint16_receiver); + test(int32_receiver); + test(uint32_receiver); + // int64 and uint64 in separate test. + test(float32_receiver); + test(float64_receiver); +} + +test(f) { + asyncStart(); + return f().whenComplete(asyncEnd); +} + +// Int8 array. +Int8List initInt8() { + var int8 = new Int8List(2); + int8[0] = 10; + int8[1] = 100; + return int8; +} + +Int8List int8 = initInt8(); + +int8_receiver() { + var response = new ReceivePort(); + var remote = Isolate.spawn(int8_sender, [int8.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(int8.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(int8[i], a[i]); + } + print("int8_receiver"); + asyncEnd(); + }); +} + +int8_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(int8.length, len); + var a = new Int8List(len); + for (int i = 0; i < len; i++) { + a[i] = int8[i]; + } + r.send(a); +} + +// Uint8 array. +Uint8List initUint8() { + var uint8 = new Uint8List(2); + uint8[0] = 0xff; + uint8[1] = 0x7f; + return uint8; +} + +Uint8List uint8 = initUint8(); + +uint8_receiver() { + var response = new ReceivePort(); + var remote = Isolate.spawn(uint8_sender, [uint8.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(uint8.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(uint8[i], a[i]); + } + print("uint8_receiver"); + asyncEnd(); + }); +} + +uint8_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(uint8.length, len); + var a = new Uint8List(len); + for (int i = 0; i < len; i++) { + a[i] = uint8[i]; + } + r.send(a); +} + +// Int16 array. +Int16List initInt16() { + var int16 = new Int16List(2); + int16[0] = 1000; + int16[1] = 10000; + return int16; +} + +Int16List int16 = initInt16(); + +int16_receiver() { + var response = new ReceivePort(); + var remote = Isolate.spawn(int16_sender, [int16.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(int16.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(int16[i], a[i]); + } + print("int16_receiver"); + asyncEnd(); + }); +} + +int16_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(int16.length, len); + var a = new Int16List(len); + for (int i = 0; i < len; i++) { + a[i] = int16[i]; + } + r.send(a); +} + +// Uint16 array. +Uint16List initUint16() { + var uint16 = new Uint16List(2); + uint16[0] = 0xffff; + uint16[1] = 0x7fff; + return uint16; +} + +Uint16List uint16 = initUint16(); + +uint16_receiver() { + var response = new ReceivePort(); + var remote = Isolate.spawn(uint16_sender, [uint16.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(uint16.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(uint16[i], a[i]); + } + print("uint16_receiver"); + asyncEnd(); + }); +} + +uint16_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(uint16.length, len); + var a = new Uint16List(len); + for (int i = 0; i < len; i++) { + a[i] = uint16[i]; + } + r.send(a); +} + +// Int32 array. +Int32List initInt32() { + var int32 = new Int32List(2); + int32[0] = 100000; + int32[1] = 1000000; + return int32; +} + +Int32List int32 = initInt32(); + +int32_receiver() { + var response = new ReceivePort(); + var remote = Isolate.spawn(int32_sender, [int32.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(int32.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(int32[i], a[i]); + } + print("int32_receiver"); + asyncEnd(); + }); +} + +int32_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(int32.length, len); + var a = new Int32List(len); + for (int i = 0; i < len; i++) { + a[i] = int32[i]; + } + r.send(a); +} + +// Uint32 array. +Uint32List initUint32() { + var uint32 = new Uint32List(2); + uint32[0] = 0xffffffff; + uint32[1] = 0x7fffffff; + return uint32; +} + +Uint32List uint32 = initUint32(); + +uint32_receiver() { + var response = new ReceivePort(); + var remote = Isolate.spawn(uint32_sender, [uint32.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(uint32.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(uint32[i], a[i]); + } + print("uint32_receiver"); + asyncEnd(); + }); +} + +uint32_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(uint32.length, len); + var a = new Uint32List(len); + for (int i = 0; i < len; i++) { + a[i] = uint32[i]; + } + r.send(a); +} + +// Float32 Array. +Float32List initFloat32() { + var float32 = new Float32List(2); + float32[0] = 1.0; + float32[1] = 2.0; + return float32; +} + +Float32List float32 = initFloat32(); + +float32_receiver() { + var response = new ReceivePort(); + var remote = + Isolate.spawn(float32_sender, [float32.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(float32.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(float32[i], a[i]); + } + print("float32_receiver"); + asyncEnd(); + }); +} + +float32_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(float32.length, len); + var a = new Float32List(len); + for (int i = 0; i < len; i++) { + a[i] = float32[i]; + } + r.send(a); +} + +// Float64 Array. +Float64List initFloat64() { + var float64 = new Float64List(2); + float64[0] = 101.234; + float64[1] = 201.765; + return float64; +} + +Float64List float64 = initFloat64(); + +float64_receiver() { + var response = new ReceivePort(); + var remote = + Isolate.spawn(float64_sender, [float64.length, response.sendPort]); + asyncStart(); + return response.first.then((a) { + Expect.equals(float64.length, a.length); + for (int i = 0; i < a.length; i++) { + Expect.equals(float64[i], a[i]); + } + print("float64_receiver"); + asyncEnd(); + }); +} + +float64_sender(message) { + var len = message[0]; + var r = message[1]; + Expect.equals(float64.length, len); + var a = new Float64List(len); + for (int i = 0; i < len; i++) { + a[i] = float64[i]; + } + r.send(a); +} diff --git a/tests/standalone/typed_data_isolate_test.dart b/tests/standalone/typed_data_isolate_test.dart new file mode 100644 index 00000000000..ab20d49b212 --- /dev/null +++ b/tests/standalone/typed_data_isolate_test.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--enable-isolate-groups +// VMOptions=--no-enable-isolate-groups +// +// Dart test program for testing typed data. + +// Library tag to be able to run in html test framework. +library TypedDataIsolateTest; + +import 'dart:io'; +import 'dart:isolate'; +import 'package:async_helper/async_helper.dart'; + +second(message) { + var data = message[0]; + var replyTo = message[1]; + print('got data'); + print(data); + print('printed data'); + replyTo.send('OK'); +} + +main() { + asyncStart(); + new File(Platform.script.toFilePath()).readAsBytes().then((List data) { + var response = new ReceivePort(); + var remote = Isolate.spawn(second, [data, response.sendPort]); + response.first.then((reply) { + print('got reply'); + asyncEnd(); + }); + }); +} diff --git a/tests/standalone/typed_data_test.dart b/tests/standalone/typed_data_test.dart new file mode 100644 index 00000000000..c9323100a52 --- /dev/null +++ b/tests/standalone/typed_data_test.dart @@ -0,0 +1,583 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart test program for testing typed data. + +// VMOptions=--optimization_counter_threshold=10 --no-background_compilation + +// Library tag to be able to run in html test framework. +library TypedDataTest; + +import "package:expect/expect.dart"; +import 'dart:typed_data'; + +void testCreateUint8TypedData() { + Uint8List typed_data; + + typed_data = new Uint8List(0); + Expect.isTrue(typed_data is Uint8List); + Expect.isFalse(typed_data is Uint8ClampedList); + Expect.equals(0, typed_data.length); + + typed_data = new Uint8List(10); + Expect.equals(10, typed_data.length); + for (int i = 0; i < 10; i++) { + Expect.equals(0, typed_data[i]); + } +} + +void testCreateClampedUint8TypedData() { + Uint8ClampedList typed_data; + + typed_data = new Uint8ClampedList(0); + Expect.isTrue(typed_data is Uint8ClampedList); + Expect.isFalse(typed_data is Uint8List); + Expect.equals(0, typed_data.length); + Expect.equals(0, typed_data.lengthInBytes); + + typed_data = new Uint8ClampedList(10); + Expect.equals(10, typed_data.length); + for (int i = 0; i < 10; i++) { + Expect.equals(0, typed_data[i]); + } +} + +void testTypedDataRange(bool check_throws) { + Int8List typed_data; + typed_data = new Int8List(10); + typed_data[1] = 0; + Expect.equals(0, typed_data[1]); + typed_data[2] = -128; + Expect.equals(-128, typed_data[2]); + typed_data[3] = 127; + Expect.equals(127, typed_data[3]); + // This should eventually throw. + typed_data[0] = 128; + typed_data[4] = -129; + Expect.throws(() => typed_data[-1]); + Expect.throws(() => typed_data[100]); +} + +void testUnsignedTypedDataRange(bool check_throws) { + Uint8List typed_data; + typed_data = new Uint8List(10); + + typed_data[1] = 255; + Expect.equals(255, typed_data[1]); + typed_data[1] = 0; + Expect.equals(0, typed_data[1]); + + for (int i = 0; i < typed_data.length; i++) { + typed_data[i] = i; + } + for (int i = 0; i < typed_data.length; i++) { + Expect.equals(i, typed_data[i]); + } + + // These should eventually throw. + typed_data[1] = 256; + typed_data[1] = -1; + typed_data[2] = -129; + Expect.throws(() => typed_data[-1]); + Expect.throws(() => typed_data[100]); +} + +void testClampedUnsignedTypedDataRangeHelper( + Uint8ClampedList typed_data, bool check_throws) { + Uint8ClampedList typed_data; + typed_data = new Uint8ClampedList(10); + + typed_data[1] = 255; + Expect.equals(255, typed_data[1]); + typed_data[1] = 0; + Expect.equals(0, typed_data[1]); + for (int i = 0; i < typed_data.length; i++) { + typed_data[i] = i; + } + for (int i = 0; i < typed_data.length; i++) { + Expect.equals(i, typed_data[i]); + } + + // These should eventually throw. + typed_data[1] = 256; + typed_data[2] = -129; + Expect.equals(255, typed_data[1]); + Expect.equals(0, typed_data[2]); +} + +void testClampedUnsignedTypedDataRange(bool check_throws) { + testClampedUnsignedTypedDataRangeHelper( + new Uint8ClampedList(10), check_throws); +} + +void testSetRangeHelper(typed_data) { + List list = [10, 11, 12]; + typed_data.setRange(0, 3, list); + for (int i = 0; i < 3; i++) { + Expect.equals(10 + i, typed_data[i]); + } + + typed_data[0] = 20; + typed_data[1] = 21; + typed_data[2] = 22; + list.setRange(0, 3, typed_data); + for (int i = 0; i < 3; i++) { + Expect.equals(20 + i, list[i]); + } + + typed_data.setRange(1, 3, const [8, 9]); + Expect.equals(20, typed_data[0]); + Expect.equals(8, typed_data[1]); + Expect.equals(9, typed_data[2]); +} + +void testSetRange() { + testSetRangeHelper(new Uint8List(3)); + testSetRangeHelper(new Uint8ClampedList(3)); + testSetRangeHelper(new Uint16List(3)); + testSetRangeHelper(new Int16List(3)); + + var list; + list = new Uint8List(4); + list.setRange(0, 4, "abcd".codeUnits, 0); + Expect.listEquals(list, "abcd".codeUnits); + list = new Uint16List(4); + list.setRange(0, 4, "abcd".codeUnits, 0); + Expect.listEquals(list, "abcd".codeUnits); + list.setRange(0, 4, "\xff\u0100\uffff\x00".codeUnits, 0); + Expect.listEquals(list, "\xff\u0100\uffff\x00".codeUnits); + list = new Int16List(4); + list.setRange(0, 4, "abcd".codeUnits, 0); + Expect.listEquals(list, "abcd".codeUnits); + list.setRange(0, 4, "\xff\u0100\u7fff\x00".codeUnits, 0); + Expect.listEquals(list, "\xff\u0100\u7fff\x00".codeUnits); +} + +class C { + final x; + C(this.x); + operator <(o) => false; + operator >=(o) => false; + operator *(o) => x; +} + +void testIndexOutOfRangeHelper(typed_data, value) { + List list = new List.filled(typed_data.length + 1, -1); + for (int i = 0; i < list.length; i++) list[i] = i; + + Expect.throws(() { + typed_data.setRange(0, 4, list); + }); + + Expect.throws(() { + typed_data.setRange(3, 4, list); + }); + + Expect.throws(() { + typed_data[new C(-4000000)] = value; + }); + + Expect.throws(() { + var size = typed_data.elementSizeInBytes; + var i = (typed_data.length - 1) * size + 1; + typed_data[new C(i)] = value; + }); + + Expect.throws(() { + typed_data[new C(-1)] = value; + }); +} + +void testIndexOutOfRange() { + testIndexOutOfRangeHelper(new Int8List(3), 0); + testIndexOutOfRangeHelper(new Uint8List(3), 0); + testIndexOutOfRangeHelper(new Uint8ClampedList(3), 0); + testIndexOutOfRangeHelper(new Int16List(3), 0); + testIndexOutOfRangeHelper(new Uint16List(3), 0); + testIndexOutOfRangeHelper(new Int32List(3), 0); + testIndexOutOfRangeHelper(new Uint32List(3), 0); + testIndexOutOfRangeHelper(new Int64List(3), 0); + testIndexOutOfRangeHelper(new Uint64List(3), 0); + testIndexOutOfRangeHelper(new Float32List(3), 0.0); + testIndexOutOfRangeHelper(new Float64List(3), 0.0); + testIndexOutOfRangeHelper(new Int64List(3), 0); + testIndexOutOfRangeHelper(new Uint64List(3), 0); +} + +void testNoNullValueLoopSetter(list, value) { + for (int i = 0; i < list.length; i++) { + list[i] = value; + } +} + +void testNoNullValueDirectSetter(list, value) { + list[0] = value; + list[1] = value; + list[2] = value; +} + +void testNoNullValueHelper(list, value) { + testNoNullValueLoopSetter(list, value + 1); + for (int i = 0; i < list.length; i++) { + Expect.equals(value + 1, list[i]); + } + testNoNullValueDirectSetter(list, value + 2); + for (int i = 0; i < list.length; i++) { + Expect.equals(value + 2, list[i]); + } + + Expect.throws(() { + testNoNullValueLoopSetter(list, null); + }); + + Expect.throws(() { + testNoNullValueDirectSetter(list, null); + }); +} + +void testNoNullValue() { + testNoNullValueHelper(new Int8List(3), 1); + testNoNullValueHelper(new Uint8List(3), 1); + testNoNullValueHelper(new Uint8ClampedList(3), 1); + testNoNullValueHelper(new Int16List(3), 1); + testNoNullValueHelper(new Uint16List(3), 1); + testNoNullValueHelper(new Int32List(3), 1); + testNoNullValueHelper(new Uint32List(3), 1); + testNoNullValueHelper(new Int64List(3), 1); + testNoNullValueHelper(new Uint64List(3), 1); + testNoNullValueHelper(new Float32List(3), 1.0); + testNoNullValueHelper(new Float64List(3), 1.0); + testNoNullValueHelper(new Int64List(3), 1); + testNoNullValueHelper(new Uint64List(3), 1); +} + +void testIndexOfHelper(list) { + for (int i = 0; i < list.length; i++) { + list[i] = i + 10; + } + Expect.equals(0, list.indexOf(10)); + Expect.equals(5, list.indexOf(15)); + Expect.equals(9, list.indexOf(19)); + Expect.equals(-1, list.indexOf(20)); + + list = new Float32List(10); + for (int i = 0; i < list.length; i++) { + list[i] = i + 10.0; + } + Expect.equals(0, list.indexOf(10.0)); + Expect.equals(5, list.indexOf(15.0)); + Expect.equals(9, list.indexOf(19.0)); + Expect.equals(-1, list.indexOf(20.0)); +} + +void testIndexOf() { + testIndexOfHelper(new Uint8List(10)); + testIndexOfHelper(new Uint8ClampedList(10)); +} + +void testGetAtIndex(TypedData list, num initial_value) { + var bdata = new ByteData.view(list.buffer); + for (int i = 0; i < bdata.lengthInBytes; i++) { + Expect.equals(42, bdata.getUint8(i)); + Expect.equals(42, bdata.getInt8(i)); + } + for (int i = 0; i < bdata.lengthInBytes - 1; i += 2) { + Expect.equals(10794, bdata.getUint16(i, Endian.little)); + Expect.equals(10794, bdata.getInt16(i, Endian.little)); + } + for (int i = 0; i < bdata.lengthInBytes - 3; i += 4) { + Expect.equals(707406378, bdata.getUint32(i, Endian.little)); + Expect.equals(707406378, bdata.getInt32(i, Endian.little)); + Expect.equals(1.511366173271439e-13, bdata.getFloat32(i, Endian.little)); + } + for (int i = 0; i < bdata.lengthInBytes - 7; i += 8) { + Expect.equals(3038287259199220266, bdata.getUint64(i, Endian.little)); + Expect.equals(3038287259199220266, bdata.getInt64(i, Endian.little)); + Expect.equals(1.4260258159703532e-105, bdata.getFloat64(i, Endian.little)); + } +} + +void testSetAtIndex(List list, num initial_value, [bool use_double = false]) { + void validate([reinit = true]) { + for (int i = 0; i < list.length; i++) { + Expect.equals(initial_value, list[i]); + if (reinit) list[i] = use_double ? 0.0 : 0; + } + } + + var bdata = new ByteData.view((list as TypedData).buffer); + for (int i = 0; i < bdata.lengthInBytes; i++) { + bdata.setUint8(i, 42); + } + validate(); + for (int i = 0; i < bdata.lengthInBytes; i++) { + bdata.setInt8(i, 42); + } + validate(); + for (int i = 0; i < bdata.lengthInBytes - 1; i += 2) { + bdata.setUint16(i, 10794, Endian.little); + } + validate(); + for (int i = 0; i < bdata.lengthInBytes - 1; i += 2) { + bdata.setInt16(i, 10794, Endian.little); + } + validate(); + for (int i = 0; i < bdata.lengthInBytes - 3; i += 4) { + bdata.setUint32(i, 707406378, Endian.little); + } + validate(); + for (int i = 0; i < bdata.lengthInBytes - 3; i += 4) { + bdata.setInt32(i, 707406378, Endian.little); + } + validate(); + for (int i = 0; i < bdata.lengthInBytes - 3; i += 4) { + bdata.setFloat32(i, 1.511366173271439e-13, Endian.little); + } + validate(); + for (int i = 0; i < bdata.lengthInBytes - 7; i += 8) { + bdata.setUint64(i, 3038287259199220266, Endian.little); + } + validate(); + for (int i = 0; i < bdata.lengthInBytes - 7; i += 8) { + bdata.setInt64(i, 3038287259199220266, Endian.little); + } + validate(); + for (int i = 0; i < bdata.lengthInBytes - 7; i += 8) { + bdata.setFloat64(i, 1.4260258159703532e-105, Endian.little); + } + validate(false); +} + +testViewCreation() { + var bytes = new Uint8List(1024).buffer; + var view; + view = new ByteData.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Uint8List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Int8List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Uint8ClampedList.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Uint16List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Int16List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Uint32List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Int32List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Uint64List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Int64List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Float32List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Float64List.view(bytes, 24); + Expect.equals(1000, view.lengthInBytes); + view = new Int32x4List.view(bytes, 16); + Expect.equals(1008, view.lengthInBytes); // Must be 16-byte aligned. + view = new Float32x4List.view(bytes, 16); + Expect.equals(1008, view.lengthInBytes); + view = new Float64x2List.view(bytes, 16); + Expect.equals(1008, view.lengthInBytes); + + view = bytes.asByteData(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asUint8List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asInt8List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asUint8ClampedList(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asUint16List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asInt16List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asUint32List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asInt32List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asUint64List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asInt64List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asFloat32List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asFloat64List(24); + Expect.equals(1000, view.lengthInBytes); + view = bytes.asInt32x4List(16); + Expect.equals(1008, view.lengthInBytes); + view = bytes.asFloat32x4List(16); + Expect.equals(1008, view.lengthInBytes); + view = bytes.asFloat64x2List(16); + Expect.equals(1008, view.lengthInBytes); + + view = bytes.asByteData(24, 800); + Expect.equals(800, view.lengthInBytes); + view = bytes.asUint8List(24, 800); + Expect.equals(800, view.lengthInBytes); + view = bytes.asInt8List(24, 800); + Expect.equals(800, view.lengthInBytes); + view = bytes.asUint8ClampedList(24, 800); + Expect.equals(800, view.lengthInBytes); + view = bytes.asUint16List(24, 400); + Expect.equals(800, view.lengthInBytes); + view = bytes.asInt16List(24, 400); + Expect.equals(800, view.lengthInBytes); + view = bytes.asUint32List(24, 200); + Expect.equals(800, view.lengthInBytes); + view = bytes.asInt32List(24, 200); + Expect.equals(800, view.lengthInBytes); + view = bytes.asUint64List(24, 100); + Expect.equals(800, view.lengthInBytes); + view = bytes.asInt64List(24, 100); + Expect.equals(800, view.lengthInBytes); + view = bytes.asFloat32List(24, 200); + Expect.equals(800, view.lengthInBytes); + view = bytes.asFloat64List(24, 100); + Expect.equals(800, view.lengthInBytes); + view = bytes.asInt32x4List(32, 50); + Expect.equals(800, view.lengthInBytes); + view = bytes.asFloat32x4List(32, 50); + Expect.equals(800, view.lengthInBytes); + view = bytes.asFloat64x2List(32, 50); + Expect.equals(800, view.lengthInBytes); +} + +testWhere() { + var bytes = new Uint8List(13); + bytes.setRange(0, 5, [1, 1, 1, 1, 1]); + Expect.equals(5, bytes.where((v) => v > 0).length); +} + +testCreationFromList() { + var intList = [ + -1000000000000000000, + -255, + -127, + 0, + 128, + 256, + 1000000000000000000 + ]; + var intLists = []; + intLists.add(new Int8List.fromList(intList)); + intLists.add(new Int16List.fromList(intList)); + intLists.add(new Int32List.fromList(intList)); + intLists.add(new Int64List.fromList(intList)); + intLists.add(new Uint8List.fromList(intList)); + intLists.add(new Uint16List.fromList(intList)); + intLists.add(new Uint32List.fromList(intList)); + intLists.add(new Uint64List.fromList(intList)); + var doubleList = [ + -123123123123.123123123123, + -123.0, + 0.0, + 123.0, + 123123123123.123123123 + ]; + var doubleLists = []; + doubleLists.add(new Float32List.fromList(doubleList)); + doubleLists.add(new Float64List.fromList(doubleList)); + for (var ints in intLists) { + for (var doubles in doubleLists) { + Expect.throws(() => ints[0] = doubles[0]); + Expect.throws(() => doubles[0] = ints[0]); + } + } +} + +void testStrings() { + test(List list) { + Uint16List uints = new Uint16List(list.length)..setAll(0, list); + String string = new String.fromCharCodes(list); + for (int i = 0; i < string.length; i++) { + for (int j = i; j < string.length; j++) { + int length = j - i; + { + Uint16List copy = new Uint16List(length); + copy.setRange(0, length, string.codeUnits, i); + Expect.listEquals(uints.sublist(i, j), copy); + } + { + Uint8List buffer = new Uint8List(length * 2 + 8); + Uint16List copy = new Uint16List.view(buffer.buffer, 4, length); + copy.setRange(0, length, string.codeUnits, i); + Expect.listEquals(uints.sublist(i, j), copy); + } + { + String copy = new String.fromCharCodes(uints, i, j); + Expect.equals(string.substring(i, j), copy); + } + } + } + } + + test([]); + test([0x00, 0x7f, 0xff]); + test([0x00, 0xdfff, 0xffff]); + test([0xd800, 0xdc00, 0x20, 0xdbff, 0xdfff]); +} + +main() { + for (int i = 0; i < 20; i++) { + testCreateUint8TypedData(); + testCreateClampedUint8TypedData(); + testTypedDataRange(false); + testUnsignedTypedDataRange(false); + testClampedUnsignedTypedDataRange(false); + testSetRange(); + testIndexOutOfRange(); + testNoNullValue(); + testIndexOf(); + + var int8list = new Int8List(128); + testSetAtIndex(int8list, 42); + testGetAtIndex(int8list, 42); + + var uint8list = new Uint8List(128); + testSetAtIndex(uint8list, 42); + testGetAtIndex(uint8list, 42); + + var int16list = new Int16List(64); + testSetAtIndex(int16list, 10794); + testGetAtIndex(int16list, 10794); + + var uint16list = new Uint16List(64); + testSetAtIndex(uint16list, 10794); + testGetAtIndex(uint16list, 10794); + + var int32list = new Int32List(32); + testSetAtIndex(int32list, 707406378); + testGetAtIndex(int32list, 707406378); + + var uint32list = new Uint32List(32); + testSetAtIndex(uint32list, 707406378); + testGetAtIndex(uint32list, 707406378); + + var int64list = new Int64List(16); + testSetAtIndex(int64list, 3038287259199220266); + testGetAtIndex(int64list, 3038287259199220266); + + var uint64list = new Uint64List(16); + testSetAtIndex(uint64list, 3038287259199220266); + testGetAtIndex(uint64list, 3038287259199220266); + + var float32list = new Float32List(32); + testSetAtIndex(float32list, 1.511366173271439e-13, true); + testGetAtIndex(float32list, 1.511366173271439e-13); + + var float64list = new Float64List(16); + testSetAtIndex(float64list, 1.4260258159703532e-105, true); + testGetAtIndex(float64list, 1.4260258159703532e-105); + } + testTypedDataRange(true); + testUnsignedTypedDataRange(true); + testViewCreation(); + testWhere(); + testCreationFromList(); + testStrings(); + testSetRange(); +} diff --git a/tests/standalone/typed_data_view_test.dart b/tests/standalone/typed_data_view_test.dart new file mode 100644 index 00000000000..cfcfb73b37c --- /dev/null +++ b/tests/standalone/typed_data_view_test.dart @@ -0,0 +1,83 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Dart test program for testing typed data. + +// Library tag to be able to run in html test framework. +library TypedDataTest; + +import "package:expect/expect.dart"; +import 'dart:typed_data'; + +validate(List list, num expected) { + for (int i = 0; i < list.length; i++) { + Expect.equals(expected, list[i]); + } +} + +testView() { + var list = new Int8List(128); + for (var i = 0; i < list.length; i++) { + list[i] = 42; + } + var ba = list.buffer; + + var slist = new Int16List.view(ba, 0, 32); + validate(slist, 10794); + var uslist = new Uint16List.view(ba, 0, 32); + validate(uslist, 10794); + + var ilist = new Int32List.view(ba, 0, 16); + validate(ilist, 707406378); + var uilist = new Uint32List.view(ba, 0, 16); + validate(uilist, 707406378); + + var llist = new Int64List.view(ba, 0, 8); + validate(llist, 3038287259199220266); + var ullist = new Uint64List.view(ba, 0, 8); + validate(ullist, 3038287259199220266); + + var flist = new Float32List.view(ba, 0, 16); + validate(flist, 1.511366173271439e-13); + var dlist = new Float64List.view(ba, 0, 8); + validate(dlist, 1.4260258159703532e-105); +} + +testSetters() { + var blist = new ByteData(128); + blist.setInt8(0, 0xffff); + Expect.equals(-1, blist.getInt8(0)); + blist.setUint8(0, 0xffff); + Expect.equals(0xff, blist.getUint8(0)); + blist.setInt16(0, 0xffffffff); + Expect.equals(-1, blist.getInt16(0, Endian.little)); + blist.setUint16(0, 0xffffffff, Endian.little); + Expect.equals(0xffff, blist.getUint16(0, Endian.little)); + blist.setInt32(0, 0xffffffffffff, Endian.little); + Expect.equals(-1, blist.getInt32(0, Endian.little)); + blist.setUint32(0, 0xffffffffffff, Endian.little); + Expect.equals(0xffffffff, blist.getUint32(0, Endian.little)); + blist.setInt64(0, 0xffffffffffffffff, Endian.little); + Expect.equals(-1, blist.getInt64(0, Endian.little)); + blist.setUint64(0, 0xffffffffffffffff, Endian.little); + Expect.equals(0xffffffffffffffff, blist.getUint64(0, Endian.little)); + blist.setInt32(0, 0xaabbccddfffffffe, Endian.little); + Expect.equals(-2, blist.getInt32(0, Endian.little)); + blist.setUint32(0, 0xaabbccddfffffffe, Endian.little); + Expect.equals(0xfffffffe, blist.getUint32(0, Endian.little)); + blist.setInt64(0, 0xfffffffffffffffe, Endian.little); + Expect.equals(-2, blist.getInt64(0, Endian.little)); + blist.setUint64(0, 0xfffffffffffffffe, Endian.little); + Expect.equals(0xfffffffffffffffe, blist.getUint64(0, Endian.little)); + + blist.setFloat32(0, 18446744073709551614.0, Endian.little); + Expect.equals(18446744073709551614.0, blist.getFloat32(0, Endian.little)); + blist.setFloat64(0, 18446744073709551614.0, Endian.little); + Expect.equals(18446744073709551614.0, blist.getFloat64(0, Endian.little)); +} + +main() { + testView(); + testSetters(); +} diff --git a/tests/standalone/unboxed_int_converter_test.dart b/tests/standalone/unboxed_int_converter_test.dart new file mode 100644 index 00000000000..5cbaa4dbd88 --- /dev/null +++ b/tests/standalone/unboxed_int_converter_test.dart @@ -0,0 +1,78 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test UnboxedIntConverter for int32. +// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation + +import "package:expect/expect.dart"; +import "dart:typed_data"; + +int32_add(a, b, c) => (a * c) + (b * c); +int32_mul(a, b, c) => (a * c) * b; +int32_sub(a, b, c) => (a * c) - (b * c); +int32_shr(a, b, c) => (a * c * b) >> 16; +int32_shl(a, b, c) => (a * c * b) << 16; +int32_xor(a, b, c) => (a * c) ^ (b * c); +int32_or(a, b, c) => (a * c) | (b * c); +int32_and(a, b, c) => (a * c) & (b * c); + +int32_to_mint(a, b) { + var sum = 0; + var j = 0; + for (var i = a; i <= b; i++) { + sum -= (j * ++j) & 0xff; + } + + return 0xffffffff + sum; +} + +mint_to_int32(a, c, d) { + return a * a * a * (c - d); +} + +uint32_to_int32(a, c) { + return (a * a * a) * (c & 0xFFFFFFFF); +} + +main() { + for (var j = 0; j < 1000; j++) { + Expect.equals(2, int32_add(1, 1, 1)); + Expect.equals(1, int32_mul(1, 1, 1)); + Expect.equals(0, int32_sub(1, 1, 1)); + Expect.equals(0, int32_shr(1, 1, 1)); + Expect.equals(1 << 16, int32_shl(1, 1, 1)); + Expect.equals(0, int32_xor(1, 1, 1)); + Expect.equals(1, int32_or(1, 1, 1)); + Expect.equals(1, int32_and(1, 1, 1)); + } + + Expect.equals(0x7ffffffe, int32_add(0x7ffffffc ~/ 2, 1, 2)); + Expect.equals(-0x80000000, int32_add(-0x7ffffffe ~/ 2, -1, 2)); + Expect.equals(-0x80000002, int32_add(-0x7ffffffe ~/ 2, -2, 2)); // Overflow. + Expect.equals(0x7ffffffe, int32_sub(0x7ffffffc ~/ 2, -1, 2)); + Expect.equals(-0x80000000, int32_sub(-0x7ffffffe ~/ 2, 1, 2)); + Expect.equals(-0x80000002, int32_sub(-0x7ffffffe ~/ 2, 2, 2)); // Overflow. + Expect.equals(-0x7ffffffe, int32_mul(0x7ffffffe ~/ 2, -1, 2)); + Expect.equals(-0x80000000, int32_mul(-0x80000000 ~/ 2, 1, 2)); + Expect.equals(0x80000000, int32_mul(-0x80000000 ~/ 2, -1, 2)); // Overflow. + Expect.equals(0x60000000, int32_xor(0x40000000 ~/ 2, 0x20000000 ~/ 2, 2)); + Expect.equals(0x00000000, int32_xor(0x40000000 ~/ 2, 0x40000000 ~/ 2, 2)); + Expect.equals(0x60000000, int32_or(0x40000000 ~/ 2, 0x20000000 ~/ 2, 2)); + Expect.equals(0x60000000, int32_or(0x60000000 ~/ 2, 0x40000000 ~/ 2, 2)); + Expect.equals(0x00000000, int32_and(0x40000000 ~/ 2, 0x20000000 ~/ 2, 2)); + Expect.equals(0x40000000, int32_and(0x60000000 ~/ 2, 0x40000000 ~/ 2, 2)); + Expect.equals(1, int32_shr(1, 1 << 16, 1)); + Expect.equals(-1 << 15, int32_shr(1 << 15, -(1 << 16), 1)); + Expect.equals(-0x080000000, int32_shl(-1 << 15, 1, 1)); + Expect.equals(-0x100000000, int32_shl(-1 << 16, 1, 1)); // Overflow. + + Expect.equals(0, int32_shr(1, 1, 1)); + Expect.equals(1 << 16, int32_shl(1, 1, 1)); + + for (var j = 0; j < 1000; j++) { + Expect.equals(4294839503, int32_to_mint(0, 1000)); + Expect.equals(-8, mint_to_int32(2, 0x100000000, 0x100000001)); + Expect.equals(8, uint32_to_int32(2, 0x100000001)); + } + Expect.equals(8 * 0x80000001, uint32_to_int32(2, 0x180000001)); +} diff --git a/tests/standalone/verbose_gc_to_bmu_script.dart b/tests/standalone/verbose_gc_to_bmu_script.dart new file mode 100644 index 00000000000..33e488c0106 --- /dev/null +++ b/tests/standalone/verbose_gc_to_bmu_script.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Testing GC, issue 1469. + +main() { + var div; + for (int i = 0; i < 200; ++i) { + List l = new List(1000000); + var m = 2; + div = (_) { + var b = l; // Was causing OutOfMemory. + }; + var lSmall = new List(3); + // Circular reference between new and old gen objects. + lSmall[0] = l; + l[0] = lSmall; + } +} diff --git a/tests/standalone/verbose_gc_to_bmu_test.dart b/tests/standalone/verbose_gc_to_bmu_test.dart new file mode 100644 index 00000000000..860e5eb09d5 --- /dev/null +++ b/tests/standalone/verbose_gc_to_bmu_test.dart @@ -0,0 +1,71 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// OtherResources=verbose_gc_to_bmu_script.dart + +// This test forks a second vm process that runs the BMU tool and verifies that +// it produces some output. This test is mainly here to ensure that the BMU +// tool compiles and runs. + +import "dart:async"; +import "dart:convert"; +import "dart:io"; + +import "package:path/path.dart"; + +// Tool script relative to the path of this test. +var toolScript = Uri.parse(Platform.executable) + .resolve("../../runtime/tools/verbose_gc_to_bmu.dart") + .toFilePath(); + +// Target script relative to this test. +var targetScript = + Platform.script.resolve("verbose_gc_to_bmu_script.dart").toFilePath(); +const minOutputLines = 20; + +void checkExitCode(targetResult) { + if (exitCode != 0) { + print("Process terminated with exit code ${exitCode}."); + exit(-1); + } +} + +void main() { + // Compute paths for tool and target relative to the path of this script. + var targetResult = + Process.runSync(Platform.executable, ["--verbose_gc", targetScript]); + checkExitCode(targetResult); + var gcLog = targetResult.stderr; + Process.start(Platform.executable, [toolScript]).then((Process process) { + // Feed the GC log of the target to the BMU tool. + process.stdin.write(gcLog); + process.stdin.close(); + var stdoutStringStream = + process.stdout.transform(utf8.decoder).transform(new LineSplitter()); + var stderrStringStream = + process.stderr.transform(utf8.decoder).transform(new LineSplitter()); + // Wait for 3 future events: stdout and stderr streams closed, and + // process terminated. + var futures = []; + var stdoutLines = []; + var stderrLines = []; + var subscription = stdoutStringStream.listen(stdoutLines.add); + futures.add(subscription.asFuture(true)); + subscription = stderrStringStream.listen(stderrLines.add); + futures.add(subscription.asFuture(true)); + futures.add(process.exitCode.then(checkExitCode)); + Future.wait(futures).then((results) { + if (stderrLines.isNotEmpty) { + print("Unexpected output on stderr:"); + print(stderrLines.join('\n')); + exit(-1); + } + if (stdoutLines.length < minOutputLines) { + print("Less than expected output on stdout:"); + print(stdoutLines.join('\n')); + exit(-1); + } + }); + }); +}