Version 0.8.10.0
svn merge -r 29655:29745 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@29746 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/barback/lib/barback.dart b/pkg/barback/lib/barback.dart
index 37c1506..25bb386 100644
--- a/pkg/barback/lib/barback.dart
+++ b/pkg/barback/lib/barback.dart
@@ -8,6 +8,7 @@
export 'src/asset_id.dart';
export 'src/asset_set.dart';
export 'src/barback.dart';
+export 'src/barback_settings.dart';
export 'src/build_result.dart';
export 'src/errors.dart' hide flattenAggregateExceptions;
export 'src/log.dart';
diff --git a/pkg/barback/lib/src/barback_settings.dart b/pkg/barback/lib/src/barback_settings.dart
new file mode 100644
index 0000000..80c276e
--- /dev/null
+++ b/pkg/barback/lib/src/barback_settings.dart
@@ -0,0 +1,61 @@
+// 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 barback.barback_settings;
+
+/// A generic settings object for providing configuration details to
+/// [Transformer]s.
+///
+/// Barback does not specify *how* this is provided to transformers. It is up
+/// to a host application to handle this. (For example, pub passes this to the
+/// transformer's constructor.)
+class BarbackSettings {
+ /// An open-ended map of configuration properties specific to this
+ /// transformer.
+ ///
+ /// The contents of the map should be serializable across isolates, but
+ /// otherwise can contain whatever you want.
+ final Map configuration;
+
+ /// The mode that user is running Barback in.
+ ///
+ /// This will be the same for all transformers in a running instance of
+ /// Barback.
+ final BarbackMode mode;
+
+ BarbackSettings(this.configuration, this.mode);
+}
+
+/// Enum-like class for specifying a mode that transformers may be run in.
+///
+/// Note that this is not a *closed* set of enum values. Host applications may
+/// define their own values for this, so a transformer relying on it should
+/// ensure that it behaves sanely with unknown values.
+class BarbackMode {
+ /// The normal mode used during development.
+ static const DEBUG = const BarbackMode._("debug");
+
+ /// The normal mode used to build an application for deploying to production.
+ static const RELEASE = const BarbackMode._("release");
+
+ /// The name of the mode.
+ ///
+ /// By convention, this is a lowercase string.
+ final String name;
+
+ /// Create a mode named [name].
+ factory BarbackMode(String name) {
+ // Use canonical instances of known names.
+ switch (name) {
+ case "debug": return BarbackMode.DEBUG;
+ case "release": return BarbackMode.RELEASE;
+ default:
+ return new BarbackMode._(name);
+ }
+ }
+
+ const BarbackMode._(this.name);
+
+ String toString() => name;
+}
diff --git a/pkg/barback/lib/src/file_pool.dart b/pkg/barback/lib/src/file_pool.dart
index ace7ae4..b8dcc6a 100644
--- a/pkg/barback/lib/src/file_pool.dart
+++ b/pkg/barback/lib/src/file_pool.dart
@@ -32,7 +32,7 @@
/// open, this will wait for a previously opened file to be closed and then
/// try again.
Stream<List<int>> openRead(File file) {
- return futureStream(_pool.checkOut().then((resource) {
+ return futureStream(_pool.request().then((resource) {
return file.openRead().transform(new StreamTransformer.fromHandlers(
handleDone: (sink) {
sink.close();
diff --git a/pkg/barback/lib/src/pool.dart b/pkg/barback/lib/src/pool.dart
index 3224fbe..23b878f 100644
--- a/pkg/barback/lib/src/pool.dart
+++ b/pkg/barback/lib/src/pool.dart
@@ -12,23 +12,23 @@
/// Manages an abstract pool of resources with a limit on how many may be in use
/// at once.
///
-/// When a resource is needed, the user should call [checkOut]. When the
-/// returned future completes with a [PoolResource], the resource may be
-/// allocated. Once the resource has been released, the user should call
-/// [PoolResource.release]. The pool will ensure that only a certain number of
-/// [PoolResource]s may be checked out at once.
+/// When a resource is needed, the user should call [request]. When the returned
+/// future completes with a [PoolResource], the resource may be allocated. Once
+/// the resource has been released, the user should call [PoolResource.release].
+/// The pool will ensure that only a certain number of [PoolResource]s may be
+/// allocated at once.
class Pool {
- /// Completers for checkouts beyond the first [_maxCheckedOutResources].
+ /// Completers for requests beyond the first [_maxAllocatedResources].
///
- /// When an item is released, the next element of [_pendingResources] will be
- /// completed.
- final _pendingResources = new Queue<Completer<PoolResource>>();
+ /// When an item is released, the next element of [_requestedResources] will
+ /// be completed.
+ final _requestedResources = new Queue<Completer<PoolResource>>();
- /// The maximum number of resources that may be checked out at once.
- final int _maxCheckedOutResources;
+ /// The maximum number of resources that may be allocated at once.
+ final int _maxAllocatedResources;
- /// The number of resources that are currently checked out.
- int _checkedOutResources = 0;
+ /// The number of resources that are currently allocated.
+ int _allocatedResources = 0;
/// The timeout timer.
///
@@ -43,43 +43,43 @@
Duration _timeout;
/// Creates a new pool with the given limit on how many resources may be
- /// checked out at once.
+ /// allocated at once.
///
/// If [timeout] is passed, then if that much time passes without any activity
- /// all pending [checkOut] futures will throw an exception. This is indented
+ /// all pending [request] futures will throw an exception. This is indented
/// to avoid deadlocks.
- Pool(this._maxCheckedOutResources, {Duration timeout})
+ Pool(this._maxAllocatedResources, {Duration timeout})
: _timeout = timeout;
- /// Check out a [PoolResource].
+ /// Request a [PoolResource].
///
- /// If the maximum number of resources is already checked out, this will delay
+ /// If the maximum number of resources is already allocated, this will delay
/// until one of them is released.
- Future<PoolResource> checkOut() {
- if (_checkedOutResources < _maxCheckedOutResources) {
- _checkedOutResources++;
+ Future<PoolResource> request() {
+ if (_allocatedResources < _maxAllocatedResources) {
+ _allocatedResources++;
return new Future.value(new PoolResource._(this));
} else {
var completer = new Completer<PoolResource>();
- _pendingResources.add(completer);
- _heartbeat();
+ _requestedResources.add(completer);
+ _resetTimer();
return completer.future;
}
}
- /// Checks out a resource for the duration of [callback], which may return a
+ /// Requests a resource for the duration of [callback], which may return a
/// Future.
///
/// The return value of [callback] is piped to the returned Future.
Future withResource(callback()) {
- return checkOut().then((resource) =>
+ return request().then((resource) =>
new Future.sync(callback).whenComplete(resource.release));
}
- /// If there are any pending checkouts, this will fire the oldest one.
+ /// If there are any pending requests, this will fire the oldest one.
void _onResourceReleased() {
- if (_pendingResources.isEmpty) {
- _checkedOutResources--;
+ if (_requestedResources.isEmpty) {
+ _allocatedResources--;
if (_timer != null) {
_timer.cancel();
_timer = null;
@@ -87,14 +87,13 @@
return;
}
- _heartbeat();
- var pending = _pendingResources.removeFirst();
+ _resetTimer();
+ var pending = _requestedResources.removeFirst();
pending.complete(new PoolResource._(this));
}
- /// Indicates that some external action has occurred and the timer should be
- /// restarted.
- void _heartbeat() {
+ /// A resource has been requested, allocated, or released.
+ void _resetTimer() {
if (_timer != null) _timer.cancel();
if (_timeout == null) {
_timer = null;
@@ -106,11 +105,11 @@
/// Handles [_timer] timing out by causing all pending resource completers to
/// emit exceptions.
void _onTimeout() {
- for (var completer in _pendingResources) {
+ for (var completer in _requestedResources) {
completer.completeException("Pool deadlock: all resources have been "
- "checked out for too long.", new Trace.current().vmTrace);
+ "allocated for too long.", new Trace.current().vmTrace);
}
- _pendingResources.clear();
+ _requestedResources.clear();
_timer = null;
}
}
@@ -128,7 +127,7 @@
PoolResource._(this._pool);
/// Tells the parent [Pool] that the resource associated with this resource is
- /// no longer allocated, and that a new [PoolResource] may be checked out.
+ /// no longer allocated, and that a new [PoolResource] may be allocated.
void release() {
if (_released) {
throw new StateError("A PoolResource may only be released once.");
diff --git a/pkg/barback/test/barback_mode_test.dart b/pkg/barback/test/barback_mode_test.dart
new file mode 100644
index 0000000..2d18f09
--- /dev/null
+++ b/pkg/barback/test/barback_mode_test.dart
@@ -0,0 +1,20 @@
+// 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 barback.test.barback_mode_test;
+
+import 'package:barback/barback.dart';
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+main() {
+ initConfig();
+ test("constructor uses canonical instances for DEBUG and RELEASE", () {
+ expect(identical(BarbackMode.DEBUG,
+ new BarbackMode(BarbackMode.DEBUG.name)), isTrue);
+ expect(identical(BarbackMode.RELEASE,
+ new BarbackMode(BarbackMode.RELEASE.name)), isTrue);
+ });
+}
diff --git a/pkg/barback/test/package_graph/repetition_test.dart b/pkg/barback/test/package_graph/repetition_test.dart
index cd98440..48462d8 100644
--- a/pkg/barback/test/package_graph/repetition_test.dart
+++ b/pkg/barback/test/package_graph/repetition_test.dart
@@ -9,6 +9,12 @@
import '../utils.dart';
+// This tests the behavior of barback under many operations happening in quick
+// succession. Since Barback is so asynchronous, it's easy for it to have subtle
+// dependencies on the commonly-used and -tested usage patterns. These tests
+// exist to stress-test less-common usage patterns in order to root out
+// additional bugs.
+
main() {
initConfig();
@@ -45,7 +51,7 @@
initGraph(["app|foo.txt"], {"app": [[rewrite]]});
updateSources(["app|foo.txt"]);
- for (var i = 0; i < 1; i++) {
+ for (var i = 0; i < 1000; i++) {
updateTransformers("app", [[rewrite]]);
}
@@ -58,7 +64,7 @@
initGraph(["app|foo.txt"], {"app": [[rewrite]]});
updateSources(["app|foo.txt"]);
- for (var i = 0; i < 1; i++) {
+ for (var i = 0; i < 1000; i++) {
updateTransformers("app", [[rewrite]]);
updateTransformers("app", [[]]);
}
diff --git a/pkg/collection_helpers/lib/equality.dart b/pkg/collection_helpers/lib/equality.dart
index c52d30f..3b5f3b4 100644
--- a/pkg/collection_helpers/lib/equality.dart
+++ b/pkg/collection_helpers/lib/equality.dart
@@ -151,21 +151,13 @@
bool isValidKey(Object o) => o is List<E>;
}
-/**
- * Equality of the elements of two iterables without considering order.
- *
- * Two iterables are considered equal if they have the same number of elements,
- * and the elements of one set can be paired with the elements
- * of the other iterable, so that each pair are equal.
- */
-class UnorderedIterableEquality<E> implements Equality<Iterable<E>> {
+abstract class _UnorderedEquality<E, T extends Iterable<E>>
+ implements Equality<T> {
final Equality<E> _elementEquality;
- const UnorderedIterableEquality(
- [Equality<E> elementEquality = const DefaultEquality()])
- : _elementEquality = elementEquality;
+ const _UnorderedEquality(this._elementEquality);
- bool equals(Iterable<E> e1, Iterable<E> e2) {
+ bool equals(T e1, T e2) {
if (identical(e1, e2)) return true;
if (e1 == null || e2 == null) return false;
HashMap<E, int> counts = new HashMap(
@@ -173,13 +165,13 @@
hashCode: _elementEquality.hash,
isValidKey: _elementEquality.isValidKey);
int length = 0;
- for (E e in e1) {
+ for (var e in e1) {
int count = counts[e];
if (count == null) count = 0;
counts[e] = count + 1;
length++;
}
- for (E e in e2) {
+ for (var e in e2) {
int count = counts[e];
if (count == null || count == 0) return false;
counts[e] = count - 1;
@@ -188,7 +180,7 @@
return length == 0;
}
- int hash(Iterable<E> e) {
+ int hash(T e) {
int hash = 0;
for (E element in e) {
int c = _elementEquality.hash(element);
@@ -199,6 +191,19 @@
hash = (hash + (hash << 15)) & _HASH_MASK;
return hash;
}
+}
+
+/**
+ * Equality of the elements of two iterables without considering order.
+ *
+ * Two iterables are considered equal if they have the same number of elements,
+ * and the elements of one set can be paired with the elements
+ * of the other iterable, so that each pair are equal.
+ */
+class UnorderedIterableEquality<E> extends _UnorderedEquality<E, Iterable<E>> {
+ const UnorderedIterableEquality(
+ [Equality<E> elementEquality = const DefaultEquality()])
+ : super(elementEquality);
bool isValidKey(Object o) => o is Iterable<E>;
}
@@ -213,16 +218,11 @@
* This equality behaves the same as [UnorderedIterableEquality] except that
* it expects sets instead of iterables as arguments.
*/
-class SetEquality<E> extends UnorderedIterableEquality<E>
- implements Equality<Set<E>> {
+class SetEquality<E> extends _UnorderedEquality<E, Set<E>> {
const SetEquality(
[Equality<E> elementEquality = const DefaultEquality()])
: super(elementEquality);
- bool equals(Set<E> e1, Set<E> e2) => super.equals(e1, e2);
-
- int hash(Set<E> e) => super.hash(e);
-
bool isValidKey(Object o) => o is Set<E>;
}
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index 1d147c7..4c1f85d 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -249,11 +249,22 @@
var libraries = !parseSdk ? _listLibraries(args) : _listSdk();
if (libraries.isEmpty) throw new StateError('No Libraries.');
// Finds the root of SDK library based off the location of docgen.
- var sdkRoot = Platform.script.resolve('../../../sdk').toFilePath();
+
+ var root = findRootDirectory();
+ var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk')));
logger.info('SDK Root: ${sdkRoot}');
return _analyzeLibraries(libraries, sdkRoot, packageRoot: packageRoot);
}
+String findRootDirectory() {
+ var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath()));
+ var root = scriptDir;
+ while(path.basename(root) != 'dart') {
+ root = path.dirname(root);
+ }
+ return root;
+}
+
/**
* Analyzes set of libraries and provides a mirror system which can be used
* for static inspection of the source code.
@@ -478,9 +489,9 @@
//Check if MDN is loaded.
if (_mdn == null) {
// Reading in MDN related json file.
- var mdnDatabase =
- Platform.script.resolve('../../../utils/apidoc/mdn/database.json');
- _mdn = JSON.decode(new File(mdnDatabase.toFilePath()).readAsStringSync());
+ var root = findRootDirectory();
+ var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
+ _mdn = JSON.decode(new File(mdnPath).readAsStringSync());
}
if (item.comment.isNotEmpty) return;
var domAnnotation = item.annotations.firstWhere(
diff --git a/pkg/http/lib/src/byte_stream.dart b/pkg/http/lib/src/byte_stream.dart
index c75654a..a154757 100644
--- a/pkg/http/lib/src/byte_stream.dart
+++ b/pkg/http/lib/src/byte_stream.dart
@@ -23,11 +23,8 @@
/// Collects the data of this stream in a [Uint8List].
Future<Uint8List> toBytes() {
- /// TODO(nweiz): use BufferList when issue 6409 is fixed.
- return fold(<int>[], (buffer, chunk) {
- buffer.addAll(chunk);
- return buffer;
- }).then(toUint8List);
+ return fold(new BytesBuilder(), (builder, chunk) => builder..add(chunk))
+ .then((builder) => builder.takeBytes());
}
/// Collect the data of this stream in a [String], decoded according to
diff --git a/pkg/polymer/lib/transformer.dart b/pkg/polymer/lib/transformer.dart
index a4f0e10..b9649ba 100644
--- a/pkg/polymer/lib/transformer.dart
+++ b/pkg/polymer/lib/transformer.dart
@@ -30,15 +30,19 @@
PolymerTransformerGroup(TransformOptions options)
: phases = _createDeployPhases(options);
- PolymerTransformerGroup.asPlugin(Map args) : this(_parseArgs(args));
+ PolymerTransformerGroup.asPlugin(BarbackSettings settings)
+ : this(_parseSettings(settings));
}
-
-TransformOptions _parseArgs(Map args) {
+TransformOptions _parseSettings(BarbackSettings settings) {
+ var args = settings.configuration;
+ bool release = settings.mode == BarbackMode.RELEASE;
+ bool jsOption = args['js'];
+ bool csp = args['csp'] == true; // defaults to false
return new TransformOptions(
entryPoints: _readEntrypoints(args['entry_points']),
- directlyIncludeJS: args['js'] != false, // default to true
- contentSecurityPolicy: args['csp'] == true); // default to false
+ directlyIncludeJS: jsOption == null ? release : jsOption,
+ contentSecurityPolicy: csp);
}
_readEntrypoints(value) {
diff --git a/runtime/lib/bool.cc b/runtime/lib/bool.cc
index ae4af27..d575745 100644
--- a/runtime/lib/bool.cc
+++ b/runtime/lib/bool.cc
@@ -24,17 +24,17 @@
Dart_EnvironmentCallback callback = isolate->environment_callback();
if (callback != NULL) {
Dart_Handle result = callback(Api::NewHandle(isolate, name.raw()));
- if (Dart_IsError(result)) {
+ if (Dart_IsString(result)) {
+ const char *chars;
+ Dart_StringToCString(result, &chars);
+ if (strcmp("true", chars) == 0) return Bool::True().raw();
+ if (strcmp("false", chars) == 0) return Bool::False().raw();
+ } else if (Dart_IsError(result)) {
const Object& error =
Object::Handle(isolate, Api::UnwrapHandle(result));
Exceptions::ThrowArgumentError(
String::Handle(
String::New(Error::Cast(error).ToErrorCString())));
- } else if (Dart_IsString(result)) {
- const char *chars;
- Dart_StringToCString(result, &chars);
- return (strcmp("true", chars) == 0)
- ? Bool::True().raw() : Bool::False().raw();
} else if (!Dart_IsNull(result)) {
Exceptions::ThrowArgumentError(
String::Handle(String::New("Illegal environment value")));
diff --git a/runtime/lib/bool_patch.dart b/runtime/lib/bool_patch.dart
index cd6b740..8259f2e 100644
--- a/runtime/lib/bool_patch.dart
+++ b/runtime/lib/bool_patch.dart
@@ -7,7 +7,7 @@
patch class bool {
/* patch */ const factory bool.fromEnvironment(String name,
- {bool defaultValue})
+ {bool defaultValue: false})
native "Bool_fromEnvironment";
int get _identityHashCode {
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index 1d93b40..4e64ea5 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -191,8 +191,8 @@
}
-DEFINE_NATIVE_ENTRY(Integer_parse, 1) {
- GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
+static RawInteger* ParseInteger(const String& value) {
+ // Used by both Integer_parse and Integer_fromEnvironment.
if (value.IsOneByteString()) {
// Quick conversion for unpadded integers in strings.
const intptr_t len = value.Length();
@@ -225,7 +225,13 @@
return Integer::New(temp);
}
- return Object::null();
+ return Integer::null();
+}
+
+
+DEFINE_NATIVE_ENTRY(Integer_parse, 1) {
+ GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
+ return ParseInteger(value);
}
@@ -235,47 +241,22 @@
// Call the embedder to supply us with the environment.
Dart_EnvironmentCallback callback = isolate->environment_callback();
if (callback != NULL) {
- Dart_Handle result = callback(Api::NewHandle(isolate, name.raw()));
- if (Dart_IsError(result)) {
+ Dart_Handle response = callback(Api::NewHandle(isolate, name.raw()));
+ if (Dart_IsString(response)) {
+ const String& value = String::Cast(
+ Object::Handle(isolate, Api::UnwrapHandle(response)));
+ const Integer& result = Integer::Handle(ParseInteger(value));
+ if (!result.IsNull()) {
+ if (result.IsSmi()) return result.raw();
+ return result.CheckAndCanonicalize(NULL);
+ }
+ } else if (Dart_IsError(response)) {
const Object& error =
- Object::Handle(isolate, Api::UnwrapHandle(result));
+ Object::Handle(isolate, Api::UnwrapHandle(response));
Exceptions::ThrowArgumentError(
String::Handle(
String::New(Error::Cast(error).ToErrorCString())));
- } else if (Dart_IsString(result)) {
- uint8_t* digits;
- intptr_t digits_len;
- Dart_StringToUTF8(result, &digits, &digits_len);
- if (digits_len > 0) {
- // Check for valid integer literal before constructing integer object.
- // Skip leading minus if present.
- if (digits[0] == '-') {
- digits++;
- digits_len--;
- }
- // Check remaining string for decimal or hex-decimal literal.
- bool is_number = true;
- if (digits_len > 2 &&
- digits[0] == '0' &&
- (digits[1] == 'x' || digits[1] == 'X')) {
- for (int i = 2; i < digits_len && is_number; i++) {
- is_number = ('0' <= digits[i] && digits[i] <= '9') ||
- ('A' <= digits[i] && digits[i] <= 'F') ||
- ('a' <= digits[i] && digits[i] <= 'f');
- }
- } else {
- for (int i = 0; i < digits_len && is_number; i++) {
- is_number = '0' <= digits[i] && digits[i] <= '9';
- }
- }
- if (digits_len > 0 && is_number) {
- const Object& value =
- Object::Handle(isolate, Api::UnwrapHandle(result));
- ASSERT(value.IsString());
- return Integer::NewCanonical(String::Cast(value));
- }
- }
- } else if (!Dart_IsNull(result)) {
+ } else if (!Dart_IsNull(response)) {
Exceptions::ThrowArgumentError(
String::Handle(String::New("Illegal environment value")));
}
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index ab7f258..df716fc 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -60,8 +60,7 @@
class_name,
function_name,
kNumArguments,
- Object::empty_array(),
- Resolver::kIsQualified);
+ Object::empty_array());
ASSERT(!func.IsNull());
isolate->object_store()->set_receive_port_create_function(func);
}
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index c11ea61..22b2d47 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -20,6 +20,9 @@
"Wrap compilation errors that occur during reflective access in a "
"MirroredCompilationError, rather than suspending the isolate.");
+DEFINE_FLAG(bool, support_find_in_context, false,
+ "Experimental support for ClosureMirror.findInContext.");
+
static RawInstance* CreateMirror(const String& mirror_class_name,
const Array& constructor_arguments) {
const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary());
@@ -721,12 +724,8 @@
return result.raw();
}
- Function& func = Function::Handle();
- Class& lookup_class = Class::Handle(klass.raw());
- while (func.IsNull() && !lookup_class.IsNull()) {
- func ^= lookup_class.LookupStaticFunction(lookup_name);
- lookup_class = lookup_class.SuperClass();
- }
+ const Function& func =
+ Function::Handle(klass.LookupStaticFunction(lookup_name));
if (!func.IsNull()) {
const Function& closure_function = Function::Handle(
func.ImplicitClosureFunction());
@@ -1376,31 +1375,12 @@
GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2));
GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3));
- String& internal_setter_name =
+ const Class& klass = Class::Handle(reflectee.clazz());
+ const String& internal_setter_name =
String::Handle(Field::SetterName(setter_name));
- Function& setter = Function::Handle();
+ const Function& setter = Function::Handle(
+ Resolver::ResolveDynamicAnyArgs(klass, internal_setter_name));
- Class& klass = Class::Handle(reflectee.clazz());
- Field& field = Field::Handle();
-
- while (!klass.IsNull()) {
- field = klass.LookupInstanceField(setter_name);
- if (!field.IsNull() && field.is_final()) {
- const String& message = String::Handle(
- String::NewFormatted("%s: cannot set final field '%s'.",
- "InstanceMirror_invokeSetter",
- setter_name.ToCString()));
- ThrowMirroredCompilationError(message);
- UNREACHABLE();
- }
- setter = klass.LookupDynamicFunction(internal_setter_name);
- if (!setter.IsNull()) {
- break;
- }
- klass = klass.SuperClass();
- }
-
- // Invoke the setter and return the result.
const int kNumArgs = 2;
const Array& args = Array::Handle(Array::New(kNumArgs));
args.SetAt(0, reflectee);
@@ -1443,6 +1423,10 @@
DEFINE_NATIVE_ENTRY(ClosureMirror_find_in_context, 2) {
+ if (!FLAG_support_find_in_context) {
+ return Object::empty_array().raw();
+ }
+
GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Array, lookup_parts, arguments->NativeArgAt(1));
ASSERT(lookup_parts.Length() >= 1 && lookup_parts.Length() <= 3);
@@ -1596,11 +1580,12 @@
// Check for real fields and user-defined setters.
const Field& field = Field::Handle(klass.LookupStaticField(setter_name));
+ Function& setter = Function::Handle();
if (field.IsNull()) {
const String& internal_setter_name = String::Handle(
Field::SetterName(setter_name));
- const Function& setter = Function::Handle(
- klass.LookupStaticFunction(internal_setter_name));
+
+ setter = klass.LookupStaticFunction(internal_setter_name);
if (setter.IsNull() || !setter.is_visible()) {
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
@@ -1626,11 +1611,11 @@
}
if (field.is_final()) {
- const String& message = String::Handle(
- String::NewFormatted("%s: cannot set final field '%s'.",
- "ClassMirror_invokeSetter",
- setter_name.ToCString()));
- ThrowMirroredCompilationError(message);
+ ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
+ setter_name,
+ setter,
+ InvocationMirror::kStatic,
+ InvocationMirror::kSetter);
UNREACHABLE();
}
@@ -1848,12 +1833,13 @@
// library or in the field's owner class, depending.
const Field& field = Field::Handle(
library.LookupLocalField(setter_name));
+ Function& setter = Function::Handle();
if (field.IsNull()) {
const String& internal_setter_name =
String::Handle(Field::SetterName(setter_name));
- const Function& setter = Function::Handle(
- library.LookupLocalFunction(internal_setter_name));
+
+ setter = library.LookupLocalFunction(internal_setter_name);
if (setter.IsNull() || !setter.is_visible()) {
ThrowNoSuchMethod(Instance::null_instance(),
setter_name,
@@ -1877,11 +1863,11 @@
}
if (field.is_final()) {
- const String& message = String::Handle(
- String::NewFormatted("%s: cannot set final top-level variable '%s'.",
- "LibraryMirror_invokeSetter",
- setter_name.ToCString()));
- ThrowMirroredCompilationError(message);
+ ThrowNoSuchMethod(Instance::null_instance(),
+ setter_name,
+ setter,
+ InvocationMirror::kTopLevel,
+ InvocationMirror::kSetter);
UNREACHABLE();
}
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 85bbae8..6f76866 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -121,40 +121,6 @@
List _metadata(reflectee)
native 'DeclarationMirror_metadata';
-// This will verify the argument types, unwrap them, and ensure we have a fixed
-// array.
-List _unwrapAsyncPositionals(wrappedArgs) {
- List unwrappedArgs = new List(wrappedArgs.length);
- for(int i = 0; i < wrappedArgs.length; i++){
- var wrappedArg = wrappedArgs[i];
- if(_isSimpleValue(wrappedArg)) {
- unwrappedArgs[i] = wrappedArg;
- } else if(wrappedArg is InstanceMirror) {
- unwrappedArgs[i] = wrappedArg._reflectee;
- } else {
- throw "positional argument $i ($wrappedArg) was "
- "not a simple value or InstanceMirror";
- }
- }
- return unwrappedArgs;
-}
-
-Map _unwrapAsyncNamed(wrappedArgs) {
- if (wrappedArgs==null) return null;
- Map unwrappedArgs = new Map();
- wrappedArgs.forEach((name, wrappedArg){
- if(_isSimpleValue(wrappedArg)) {
- unwrappedArgs[name] = wrappedArg;
- } else if(wrappedArg is InstanceMirror) {
- unwrappedArgs[name] = wrappedArg._reflectee;
- } else {
- throw "named argument ${_n(name)} ($wrappedArg) was "
- "not a simple value or InstanceMirror";
- }
- });
- return unwrappedArgs;
-}
-
class _LocalMirrorSystemImpl extends MirrorSystem {
// Change parameter back to "this.libraries" when native code is changed.
_LocalMirrorSystemImpl(List<LibraryMirror> libraries, this.isolate)
@@ -183,11 +149,7 @@
String toString() => "MirrorSystem for isolate '${isolate.debugName}'";
}
-abstract class _LocalMirrorImpl implements Mirror {
- // Local mirrors always return the same MirrorSystem. This field
- // is more interesting once we implement remote mirrors.
- MirrorSystem get mirrors => _Mirrors.currentMirrorSystem();
-}
+abstract class _LocalMirrorImpl implements Mirror {}
class _LocalIsolateMirrorImpl extends _LocalMirrorImpl
implements IsolateMirror {
@@ -255,47 +217,6 @@
return reflect(value);
}
- Future<InstanceMirror> invokeAsync(Symbol memberName,
- List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return new Future(() {
- return this.invoke(memberName,
- _unwrapAsyncPositionals(positionalArguments),
- _unwrapAsyncNamed(namedArguments));
- });
- }
-
- Future<InstanceMirror> getFieldAsync(Symbol memberName) {
- try {
- var result = this._invokeGetter(_reflectee,
- _n(memberName));
- return new Future.value(reflect(result));
- } catch(e) {
- return new Future.error(e);
- }
- }
-
- Future<InstanceMirror> setFieldAsync(Symbol memberName, Object value) {
- try {
- var unwrappedValue;
- if(_isSimpleValue(value)) {
- unwrappedValue = value;
- } else if(value is InstanceMirror) {
- unwrappedValue = value._reflectee;
- } else {
- throw "setter argument ($value) must be"
- "a simple value or InstanceMirror";
- }
-
- this._invokeSetter(_reflectee,
- _n(memberName),
- unwrappedValue);
- return new Future.value(reflect(unwrappedValue));
- } catch(e) {
- return new Future.error(e);
- }
- }
-
static _validateArgument(int i, Object arg)
{
if (arg is Mirror) {
@@ -469,6 +390,10 @@
throw new ArgumentError("Invalid symbol: ${name}");
}
List tuple = _computeFindInContext(_reflectee, parts);
+ if (tuple.length == 0) {
+ throw new UnsupportedError(
+ "ClosureMirror.findInContext not yet supported");
+ }
if (tuple[0]) {
return reflect(tuple[1]);
}
@@ -550,11 +475,6 @@
throw new UnimplementedError('ClassMirror.location is not implemented');
}
- // TODO(rmacnak): Remove these left-overs from the days of separate interfaces
- // once we send out a breaking change.
- bool get isClass => true;
- ClassMirror get defaultFactory => null;
-
ClassMirror _trueSuperclassField;
ClassMirror get _trueSuperclass {
if (_trueSuperclassField == null) {
@@ -1528,21 +1448,6 @@
return _currentMirrorSystem;
}
- static Future<MirrorSystem> mirrorSystemOf(SendPort port) {
- if (isLocalPort(port)) {
- // Make a local mirror system.
- try {
- return new Future<MirrorSystem>.value(currentMirrorSystem());
- } catch (exception) {
- return new Future<MirrorSystem>.error(exception);
- }
- } else {
- // Make a remote mirror system
- throw new UnimplementedError(
- 'Remote mirror support is not implemented');
- }
- }
-
// Creates a new local mirror for some Object.
static InstanceMirror reflect(Object reflectee) {
return reflectee is Function
diff --git a/runtime/lib/mirrors_patch.dart b/runtime/lib/mirrors_patch.dart
index b3f2d4d..200b1b0 100644
--- a/runtime/lib/mirrors_patch.dart
+++ b/runtime/lib/mirrors_patch.dart
@@ -14,14 +14,6 @@
}
/**
- * Creates a [MirrorSystem] for the isolate which is listening on
- * the [SendPort].
- */
-Future<MirrorSystem> mirrorSystemOf(SendPort port) {
- return _Mirrors.mirrorSystemOf(port);
-}
-
-/**
* Returns an [InstanceMirror] for some Dart language object.
*
* This only works if this mirror system is associated with the
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index 8f3cc3e..d2aaf68 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -11,6 +11,18 @@
namespace dart {
+static void ThrowMaskRangeException(int64_t m) {
+ if ((m < 0) || (m > 255)) {
+ const String& error = String::Handle(
+ String::NewFormatted("mask (%" Pd64 ") must be in the range [0..256)",
+ m));
+ const Array& args = Array::Handle(Array::New(1));
+ args.SetAt(0, error);
+ Exceptions::ThrowByType(Exceptions::kRange, args);
+ }
+}
+
+
DEFINE_NATIVE_ENTRY(Float32x4_fromDoubles, 5) {
ASSERT(AbstractTypeArguments::CheckedHandle(
arguments->NativeArgAt(0)).IsNull());
@@ -263,14 +275,7 @@
GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(1));
int64_t m = mask.AsInt64Value();
- if (m < 0 || m > 255) {
- const String& error = String::Handle(
- String::NewFormatted("mask (%" Pd64 ") must be in the range [0..256)",
- m));
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, error);
- Exceptions::ThrowByType(Exceptions::kRange, args);
- }
+ ThrowMaskRangeException(m);
float data[4] = { self.x(), self.y(), self.z(), self.w() };
float _x = data[m & 0x3];
float _y = data[(m >> 2) & 0x3];
@@ -280,57 +285,18 @@
}
-DEFINE_NATIVE_ENTRY(Float32x4_withZWInXY, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_shuffleMix, 3) {
GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
- float _x = other.z();
- float _y = other.w();
- float _z = self.z();
- float _w = self.w();
- return Float32x4::New(_x, _y, _z, _w);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_interleaveXY, 2) {
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
- float _x = self.x();
- float _y = other.x();
- float _z = self.y();
- float _w = other.y();
- return Float32x4::New(_x, _y, _z, _w);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_interleaveZW, 2) {
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
- float _x = self.z();
- float _y = other.z();
- float _z = self.w();
- float _w = other.w();
- return Float32x4::New(_x, _y, _z, _w);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_interleaveXYPairs, 2) {
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
- float _x = self.x();
- float _y = self.y();
- float _z = other.x();
- float _w = other.y();
- return Float32x4::New(_x, _y, _z, _w);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_interleaveZWPairs, 2) {
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
- float _x = self.z();
- float _y = self.w();
- float _z = other.z();
- float _w = other.w();
+ GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2));
+ int64_t m = mask.AsInt64Value();
+ ThrowMaskRangeException(m);
+ float data[4] = { self.x(), self.y(), self.z(), self.w() };
+ float other_data[4] = { other.x(), other.y(), other.z(), other.w() };
+ float _x = data[m & 0x3];
+ float _y = data[(m >> 2) & 0x3];
+ float _z = other_data[(m >> 4) & 0x3];
+ float _w = other_data[(m >> 6) & 0x3];
return Float32x4::New(_x, _y, _z, _w);
}
@@ -552,6 +518,36 @@
}
+DEFINE_NATIVE_ENTRY(Uint32x4_shuffle, 2) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(1));
+ int64_t m = mask.AsInt64Value();
+ ThrowMaskRangeException(m);
+ uint32_t data[4] = { self.x(), self.y(), self.z(), self.w() };
+ uint32_t _x = data[m & 0x3];
+ uint32_t _y = data[(m >> 2) & 0x3];
+ uint32_t _z = data[(m >> 4) & 0x3];
+ uint32_t _w = data[(m >> 6) & 0x3];
+ return Uint32x4::New(_x, _y, _z, _w);
+}
+
+
+DEFINE_NATIVE_ENTRY(Uint32x4_shuffleMix, 3) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, zw, arguments->NativeArgAt(1));
+ GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2));
+ int64_t m = mask.AsInt64Value();
+ ThrowMaskRangeException(m);
+ uint32_t data[4] = { self.x(), self.y(), self.z(), self.w() };
+ uint32_t zw_data[4] = { zw.x(), zw.y(), zw.z(), zw.w() };
+ uint32_t _x = data[m & 0x3];
+ uint32_t _y = data[(m >> 2) & 0x3];
+ uint32_t _z = zw_data[(m >> 4) & 0x3];
+ uint32_t _w = zw_data[(m >> 6) & 0x3];
+ return Uint32x4::New(_x, _y, _z, _w);
+}
+
+
DEFINE_NATIVE_ENTRY(Uint32x4_setX, 2) {
GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Integer, x, arguments->NativeArgAt(1));
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index ba42a57..ea67ae2 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -22,16 +22,16 @@
Dart_EnvironmentCallback callback = isolate->environment_callback();
if (callback != NULL) {
Dart_Handle result = callback(Api::NewHandle(isolate, name.raw()));
- if (Dart_IsError(result)) {
+ if (Dart_IsString(result)) {
+ const Object& value =
+ Object::Handle(isolate, Api::UnwrapHandle(result));
+ return Symbols::New(String::Cast(value));
+ } else if (Dart_IsError(result)) {
const Object& error =
Object::Handle(isolate, Api::UnwrapHandle(result));
Exceptions::ThrowArgumentError(
String::Handle(
String::New(Error::Cast(error).ToErrorCString())));
- } else if (Dart_IsString(result)) {
- const Object& value =
- Object::Handle(isolate, Api::UnwrapHandle(result));
- return Symbols::New(String::Cast(value));
} else if (!Dart_IsNull(result)) {
Exceptions::ThrowArgumentError(
String::Handle(String::New("Illegal environment value")));
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index aeb2150..5339da4 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -602,6 +602,28 @@
return super.indexOf(pattern, start);
}
+ bool contains(Pattern pattern, [int start = 0]) {
+ final pCid = pattern._cid;
+ if ((pCid == _OneByteString._classId) ||
+ (pCid == _TwoByteString._classId) ||
+ (pCid == _ExternalOneByteString._classId)) {
+ final len = this.length;
+ if ((pattern.length == 1) && (start >= 0) && (start < len)) {
+ final patternCu0 = pattern.codeUnitAt(0);
+ if (patternCu0 > 0xFF) {
+ return false;
+ }
+ for (int i = start; i < len; i++) {
+ if (this.codeUnitAt(i) == patternCu0) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ return super.contains(pattern, start);
+ }
+
// Allocates a string of given length, expecting its content to be
// set using _setAt.
static _OneByteString _allocate(int length) native "OneByteString_allocate";
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index 2c1123a..27a41f5 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -2168,14 +2168,7 @@
int get signMask native "Float32x4_getSignMask";
Float32x4 shuffle(int mask) native "Float32x4_shuffle";
-
- Float32x4 withZWInXY(Float32x4 other) native "Float32x4_withZWInXY";
- Float32x4 interleaveXY(Float32x4 other) native "Float32x4_interleaveXY";
- Float32x4 interleaveZW(Float32x4 other) native "Float32x4_interleaveZW";
- Float32x4 interleaveXYPairs(Float32x4 other)
- native "Float32x4_interleaveXYPairs";
- Float32x4 interleaveZWPairs(Float32x4 other)
- native "Float32x4_interleaveZWPairs";
+ Float32x4 shuffleMix(Float32x4 zw, int mask) native "Float32x4_shuffleMix";
Float32x4 withX(double x) native "Float32x4_setX";
Float32x4 withY(double y) native "Float32x4_setY";
@@ -2236,6 +2229,8 @@
int get z native "Uint32x4_getZ";
int get w native "Uint32x4_getW";
int get signMask native "Uint32x4_getSignMask";
+ Uint32x4 shuffle(int mask) native "Uint32x4_shuffle";
+ Uint32x4 shuffleMix(Uint32x4 zw, int mask) native "Uint32x4_shuffleMix";
Uint32x4 withX(int x) native "Uint32x4_setX";
Uint32x4 withY(int y) native "Uint32x4_setY";
Uint32x4 withZ(int z) native "Uint32x4_setZ";
diff --git a/runtime/tests/vm/dart/isolate_mirror_local_test.dart b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
deleted file mode 100644
index e5ca82e..0000000
--- a/runtime/tests/vm/dart/isolate_mirror_local_test.dart
+++ /dev/null
@@ -1,505 +0,0 @@
-// 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 checking implemention of MirrorSystem when
-// inspecting the current isolate.
-//
-// VMOptions=--enable_type_checks
-
-library isolate_mirror_local_test;
-
-import "package:expect/expect.dart";
-import 'dart:async';
-import 'dart:isolate';
-import 'dart:mirrors';
-
-ReceivePort exit_port;
-Set expectedTests;
-
-void testDone(String test) {
- if (!expectedTests.contains(test)) {
- throw "Unexpected test name '$test'";
- }
- expectedTests.remove(test);
- if (expectedTests.isEmpty) {
- // All tests are done.
- exit_port.close();
- }
-}
-
-int global_var = 0;
-final int final_global_var = 0;
-
-// Top-level getter and setter.
-int get myVar { return 5; }
-void set myVar(x) {}
-
-// This function will be invoked reflectively.
-int function(int x) {
- global_var = x;
- return x + 1;
-}
-
-typedef void FuncType(String a);
-
-FuncType myFunc = null;
-
-_stringCompare(String a, String b) => a.compareTo(b);
-sort(list) => list.sort(_stringCompare);
-
-String buildMethodString(MethodMirror func) {
- var result = '${MirrorSystem.getName(func.simpleName)} '
- 'return(${MirrorSystem.getName(func.returnType.simpleName)})';
- if (func.isPrivate) {
- result = '$result private';
- }
- if (func.isTopLevel) {
- result = '$result toplevel';
- }
- if (func.isStatic) {
- result = '$result static';
- }
- if (func.isAbstract) {
- result = '$result abstract';
- }
- if (func.isRegularMethod) {
- result = '$result method';
- }
- if (func.isGetter) {
- result = '$result getter';
- }
- if (func.isSetter) {
- result = '$result setter';
- }
- if (func.isConstructor) {
- result = '$result constructor';
- }
- if (func.isConstConstructor) {
- result = '$result const';
- }
- if (func.isGenerativeConstructor) {
- result = '$result generative';
- }
- if (func.isRedirectingConstructor) {
- result = '$result redirecting';
- }
- if (func.isFactoryConstructor) {
- result = '$result factory';
- }
- return result;
-}
-
-String buildVariableString(VariableMirror variable) {
- var result = '${MirrorSystem.getName(variable.simpleName)} '
- 'type(${MirrorSystem.getName(variable.type.simpleName)})';
- if (variable.isPrivate) {
- result = '$result private';
- }
- if (variable.isTopLevel) {
- result = '$result toplevel';
- }
- if (variable.isStatic) {
- result = '$result static';
- }
- if (variable.isFinal) {
- result = '$result final';
- }
- return result;
-}
-
-void testRootLibraryMirror(LibraryMirror lib_mirror) {
- Expect.equals(const Symbol('isolate_mirror_local_test'),
- lib_mirror.simpleName);
- Expect.equals(const Symbol('isolate_mirror_local_test'),
- lib_mirror.qualifiedName);
- Expect.equals(null, lib_mirror.owner);
- Expect.isFalse(lib_mirror.isPrivate);
- Expect.isTrue(lib_mirror.uri.path.contains('isolate_mirror_local_test.dart'));
- Expect.equals("LibraryMirror on 'isolate_mirror_local_test'",
- lib_mirror.toString());
-
- // Test library invocation by calling function(123).
- Expect.equals(0, global_var);
- lib_mirror.invokeAsync(const Symbol('function'), [123]).then(
- (InstanceMirror retval) {
- Expect.equals(123, global_var);
- testImplements(retval.type, #int);
- Expect.isTrue(retval.hasReflectee);
- Expect.equals(124, retval.reflectee);
- testDone('testRootLibraryMirror');
- });
-
- // Check that the members map is complete.
- List keys = lib_mirror.members.keys.map(MirrorSystem.getName).toList();
- sort(keys);
- Expect.equals('['
- 'FuncType, '
- 'GenericClass, '
- 'MyClass, '
- 'MyException, '
- 'MyInterface, '
- 'MySuperClass, '
- '_stringCompare, '
- 'buildMethodString, '
- 'buildVariableString, '
- 'exit_port, '
- 'expectedTests, '
- 'final_global_var, '
- 'function, '
- 'global_var, '
- 'main, '
- 'myFunc, '
- 'myVar, '
- 'myVar=, '
- 'sort, '
- 'testBoolInstanceMirror, '
- 'testCustomInstanceMirror, '
- 'testDone, '
- 'testImplements, '
- 'testIntegerInstanceMirror, '
- 'testLibrariesMap, '
- 'testMirrorSystem, '
- 'testNullInstanceMirror, '
- 'testRootLibraryMirror, '
- 'testStringInstanceMirror]',
- '$keys');
-
- // Check that the classes map is complete.
- keys = lib_mirror.classes.keys.map(MirrorSystem.getName).toList();
- sort(keys);
- print(keys);
- Expect.equals('['
- 'GenericClass, '
- 'MyClass, '
- 'MyException, '
- 'MyInterface, '
- 'MySuperClass]',
- '$keys');
-
- // Check that the types map is complete.
- keys = lib_mirror.types.keys.map(MirrorSystem.getName).toList();
- sort(keys);
- print(keys);
- Expect.equals('['
- 'FuncType, '
- 'GenericClass, '
- 'MyClass, '
- 'MyException, '
- 'MyInterface, '
- 'MySuperClass]',
- '$keys');
-
- // Check that the functions map is complete.
- keys = lib_mirror.functions.keys.map(MirrorSystem.getName).toList();
- sort(keys);
- Expect.equals('['
- '_stringCompare, '
- 'buildMethodString, '
- 'buildVariableString, '
- 'function, '
- 'main, '
- 'myVar, '
- 'myVar=, '
- 'sort, '
- 'testBoolInstanceMirror, '
- 'testCustomInstanceMirror, '
- 'testDone, '
- 'testImplements, '
- 'testIntegerInstanceMirror, '
- 'testLibrariesMap, '
- 'testMirrorSystem, '
- 'testNullInstanceMirror, '
- 'testRootLibraryMirror, '
- 'testStringInstanceMirror]',
- '$keys');
-
- // Check that the getters map is complete.
- keys = lib_mirror.getters.keys.map(MirrorSystem.getName).toList();
- sort(keys);
- Expect.equals('[myVar]', '$keys');
-
- // Check that the setters map is complete.
- keys = lib_mirror.setters.keys.map(MirrorSystem.getName).toList();
- sort(keys);
- Expect.equals('[myVar=]', '$keys');
-
- // Check that the variables map is complete.
- keys = lib_mirror.variables.keys.map(MirrorSystem.getName).toList();
- sort(keys);
- Expect.equals('['
- 'exit_port, '
- 'expectedTests, '
- 'final_global_var, '
- 'global_var, '
- 'myFunc]',
- '$keys');
-
- ClassMirror cls_mirror = lib_mirror.members[const Symbol('MyClass')];
- ClassMirror generic_cls_mirror =
- lib_mirror.members[const Symbol('GenericClass')];
-
- // Test function mirrors.
- MethodMirror func = lib_mirror.members[const Symbol('function')];
- Expect.isTrue(func is MethodMirror);
- Expect.equals('function return(int) toplevel static method',
- buildMethodString(func));
-
- func = lib_mirror.members[const Symbol('myVar')];
- Expect.isTrue(func is MethodMirror);
- Expect.equals('myVar return(int) toplevel static getter',
- buildMethodString(func));
-
- func = lib_mirror.members[const Symbol('myVar=')];
- Expect.isTrue(func is MethodMirror);
- Expect.equals('myVar= return(void) toplevel static setter',
- buildMethodString(func));
-
- func = cls_mirror.members[const Symbol('method')];
- Expect.isTrue(func is MethodMirror);
- Expect.equals('method return(int) method', buildMethodString(func));
-
- func = cls_mirror.constructors[const Symbol('MyClass')];
- Expect.isTrue(func is MethodMirror);
- Expect.equals('MyClass return(MyClass) constructor generative',
- buildMethodString(func));
-
- func = cls_mirror.constructors[const Symbol('MyClass.named')];
- Expect.isTrue(func is MethodMirror);
- Expect.equals('MyClass.named return(MyClass) constructor generative',
- buildMethodString(func));
-
- func = generic_cls_mirror.members[const Symbol('method')];
- Expect.isTrue(func is MethodMirror);
- Expect.equals('method return(T) method', buildMethodString(func));
-
- // Test variable mirrors.
- VariableMirror variable = lib_mirror.members[const Symbol('global_var')];
- Expect.isTrue(variable is VariableMirror);
- Expect.equals('global_var type(int) toplevel static',
- buildVariableString(variable));
-
- variable = lib_mirror.members[const Symbol('final_global_var')];
- Expect.isTrue(variable is VariableMirror);
- Expect.equals('final_global_var type(int) toplevel static final',
- buildVariableString(variable));
-
- variable = cls_mirror.members[const Symbol('value')];
- Expect.isTrue(variable is VariableMirror);
- Expect.equals('value type(dynamic) final', buildVariableString(variable));
-
- // Test type variable mirrors.
- var type_var = generic_cls_mirror.members[const Symbol('method')].returnType;
- Expect.isTrue(type_var is TypeVariableMirror);
- Expect.equals(const Symbol('GenericClass'), type_var.owner.simpleName);
- Expect.equals(const Symbol('Object'), type_var.upperBound.simpleName);
-
- // Test typedef mirrors.
- var typedef_mirror = lib_mirror.members[const Symbol('myFunc')].type;
- Expect.isTrue(typedef_mirror is TypedefMirror);
- Expect.equals(const Symbol('isolate_mirror_local_test'),
- typedef_mirror.owner.simpleName);
-
- // Test function type mirrors.
- var func_cls_mirror = typedef_mirror.referent;
- Expect.isTrue(func_cls_mirror is FunctionTypeMirror);
- // Expect.equals('void (dart.core.String)', func_cls_mirror.simpleName);
- Expect.equals(const Symbol('void'), func_cls_mirror.returnType.simpleName);
-}
-
-void testLibrariesMap(Map libraries) {
- // Just look for a couple of well-known libs.
- LibraryMirror core_lib = libraries[Uri.parse('dart:core')];
- Expect.isTrue(core_lib is LibraryMirror);
-
- LibraryMirror mirror_lib = libraries[Uri.parse('dart:mirrors')];
- Expect.isTrue(mirror_lib is LibraryMirror);
-
- // Lookup an interface from a library and make sure it is sane.
- ClassMirror list_intf = core_lib.members[const Symbol('List')];
- Expect.isTrue(list_intf is ClassMirror);
- Expect.equals(const Symbol('List'), list_intf.simpleName);
- Expect.equals(const Symbol('dart.core.List'), list_intf.qualifiedName);
- Expect.isFalse(list_intf.isPrivate);
- Expect.equals(const Symbol('Object'), list_intf.superclass.simpleName);
- Expect.equals(const Symbol('dart.core'), list_intf.owner.simpleName);
- Expect.isTrue(list_intf.isClass);
- Expect.equals(const Symbol('Iterable'),
- list_intf.superinterfaces[0].simpleName);
- Expect.equals("ClassMirror on 'List'", list_intf.toString());
-
- // Lookup a class from a library and make sure it is sane.
- ClassMirror oom_cls = core_lib.members[const Symbol('OutOfMemoryError')];
- Expect.isTrue(oom_cls is ClassMirror);
- Expect.equals(const Symbol('OutOfMemoryError'), oom_cls.simpleName);
- Expect.equals(const Symbol('dart.core.OutOfMemoryError'),
- oom_cls.qualifiedName);
- Expect.isFalse(oom_cls.isPrivate);
- Expect.equals(const Symbol('Object'), oom_cls.superclass.simpleName);
- Expect.isTrue(oom_cls.defaultFactory == null);
- Expect.equals(const Symbol('dart.core'), oom_cls.owner.simpleName);
- Expect.isTrue(oom_cls.isClass);
- Expect.equals(const Symbol('Error'), oom_cls.superinterfaces[0].simpleName);
- Expect.equals("ClassMirror on 'OutOfMemoryError'",
- oom_cls.toString());
- testDone('testLibrariesMap');
-}
-
-void testMirrorSystem(MirrorSystem mirrors) {
- Expect.isTrue(mirrors.isolate.debugName.contains('main'));
- testRootLibraryMirror(mirrors.isolate.rootLibrary);
- testLibrariesMap(mirrors.libraries);
- Expect.equals(const Symbol('void'), mirrors.voidType.simpleName);
- Expect.equals(const Symbol('dynamic'), mirrors.dynamicType.simpleName);
- Expect.isTrue(mirrors.voidType is TypeMirror);
- Expect.isTrue(mirrors.dynamicType is TypeMirror);
- Expect.isFalse(mirrors.voidType is ClassMirror);
- Expect.isFalse(mirrors.dynamicType is ClassMirror);
- testDone('testMirrorSystem');
-}
-
-void testImplements(klass, intfName) {
- bool foundInterface = false;
- for (ClassMirror cm = klass; cm != null; cm = cm.superclass) {
- if (cm.simpleName == intfName) foundInterface = true;
- cm.superinterfaces.forEach((intf) {
- if (intf.simpleName == intfName) foundInterface = true;
- });
- }
- Expect.isTrue(foundInterface, '$klass should implement $intfName');
-}
-
-void testIntegerInstanceMirror(InstanceMirror mirror) {
- testImplements(mirror.type, #int);
- Expect.isTrue(mirror.hasReflectee);
- Expect.equals(1001, mirror.reflectee);
- Expect.equals("InstanceMirror on 1001", mirror.toString());
-
- // Invoke (mirror + mirror).
- mirror.invokeAsync(const Symbol('+'), [ mirror ]).then(
- (InstanceMirror retval) {
- testImplements(retval.type, #int);
- Expect.isTrue(retval.hasReflectee);
- Expect.equals(2002, retval.reflectee);
- testDone('testIntegerInstanceMirror');
- });
-}
-
-void testStringInstanceMirror(InstanceMirror mirror) {
- testImplements(mirror.type, #String);
- Expect.isTrue(mirror.hasReflectee);
- Expect.equals('This\nis\na\nString', mirror.reflectee);
- Expect.equals('InstanceMirror on "This\\nis\\na\\nString"',
- mirror.toString());
-
- // Invoke mirror[0].
- mirror.invokeAsync(const Symbol('[]'), [ 0 ]).then(
- (InstanceMirror retval) {
- testImplements(retval.type, #String);
- Expect.isTrue(retval.hasReflectee);
- Expect.equals('T', retval.reflectee);
- testDone('testStringInstanceMirror');
- });
-}
-
-void testBoolInstanceMirror(InstanceMirror mirror) {
- testImplements(mirror.type, #bool);
- Expect.isTrue(mirror.hasReflectee);
- Expect.equals(true, mirror.reflectee);
- Expect.equals("InstanceMirror on true", mirror.toString());
- testDone('testBoolInstanceMirror');
-}
-
-void testNullInstanceMirror(InstanceMirror mirror) {
- testImplements(mirror.type, #Null);
- Expect.isTrue(mirror.hasReflectee);
- Expect.equals(null, mirror.reflectee);
- Expect.equals("InstanceMirror on null", mirror.toString());
- testDone('testNullInstanceMirror');
-}
-
-class MySuperClass {
-}
-
-class MyInterface {
-}
-
-class MyClass extends MySuperClass implements MyInterface {
- MyClass(this.value) {}
- MyClass.named() {}
-
- final value;
-
- int method(int arg) {
- return arg + value;
- }
-}
-
-class GenericClass<T> {
- T method(int arg) {
- return null;
- }
-}
-
-void testCustomInstanceMirror(InstanceMirror mirror) {
- Expect.isTrue(mirror.hasReflectee);
- bool saw_exception = false;
- try {
- mirror.reflectee;
- } on MirrorException catch (me) {
- saw_exception = true;
- }
- Expect.isFalse(saw_exception);
- Expect.equals("InstanceMirror on Instance of 'MyClass'",
- mirror.toString());
-
- ClassMirror cls = mirror.type;
- Expect.isTrue(cls is ClassMirror);
- Expect.equals(const Symbol('MyClass'), cls.simpleName);
- Expect.equals(const Symbol('MySuperClass'), cls.superclass.simpleName);
- Expect.isTrue(cls.defaultFactory == null);
- Expect.equals(const Symbol('isolate_mirror_local_test'),
- cls.owner.simpleName);
- Expect.isTrue(cls.isClass);
- Expect.equals(const Symbol('MyInterface'), cls.superinterfaces[0].simpleName);
- Expect.equals("ClassMirror on 'MyClass'", cls.toString());
-
- // Invoke mirror.method(1000).
- mirror.invokeAsync(const Symbol('method'), [ 1000 ]).then(
- (InstanceMirror retval) {
- testImplements(retval.type, #int);
- Expect.isTrue(retval.hasReflectee);
- Expect.equals(1017, retval.reflectee);
- testDone('testCustomInstanceMirror');
- });
-
-}
-
-class MyException implements Exception {
- MyException(this._message);
- final String _message;
- String toString() { return 'MyException: $_message'; }
-}
-
-void main() {
- // When all of the expected tests complete, the exit_port is closed,
- // allowing the program to terminate.
- exit_port = new ReceivePort();
- expectedTests = new Set<String>.from(['testRootLibraryMirror',
- 'testLibrariesMap',
- 'testMirrorSystem',
- 'testIntegerInstanceMirror',
- 'testStringInstanceMirror',
- 'testBoolInstanceMirror',
- 'testNullInstanceMirror',
- 'testCustomInstanceMirror']);
-
- // Test that an isolate can reflect on itself.
- mirrorSystemOf(exit_port.sendPort).then(testMirrorSystem);
-
- testIntegerInstanceMirror(reflect(1001));
- testStringInstanceMirror(reflect('This\nis\na\nString'));
- testBoolInstanceMirror(reflect(true));
- testNullInstanceMirror(reflect(null));
- testCustomInstanceMirror(reflect(new MyClass(17)));
-}
diff --git a/runtime/tests/vm/dart/isolate_mirror_remote_test.dart b/runtime/tests/vm/dart/isolate_mirror_remote_test.dart
deleted file mode 100644
index 7b36cfd..0000000
--- a/runtime/tests/vm/dart/isolate_mirror_remote_test.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 checking implemention of MirrorSystem when
-// inspecting a remote isolate.
-
-library isolate_mirror_local_test;
-
-import "package:expect/expect.dart";
-import 'dart:isolate';
-import 'dart:mirrors';
-
-void isolateMain(SendPort replyTo) {
- var port = new ReceivePort();
- replyTo.send(port.sendPort);
-}
-
-void testMirrorSystem(MirrorSystem mirror) {
- Expect.fail('Should not reach here. Remote isolates not implemented.');
-}
-
-void main() {
- var response = new ReceivePort();
- Isolate.spawn(isolateMain, response.sendPort);
- response.first.then((sp) {
- try {
- mirrorSystemOf(sp).then(testMirrorSystem);
- Expect.fail('Should not reach here. Remote isolates not implemented.');
- } catch (exception) {
- Expect.isTrue(exception is UnimplementedError);
- }
- });
-}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 704bfec..07c7ffc 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -27,12 +27,10 @@
[ $compiler == dart2js ]
dart/mirrored_compilation_error_test: Skip # VM-specific flag
dart/redirection_type_shuffling_test: Skip # Depends on lazy enforcement of type bounds
-dart/isolate_mirror*: Skip # compilers not aware of dart:mirrors
dart/byte_array_test: Skip # compilers not aware of byte arrays
dart/byte_array_optimized_test: Skip # compilers not aware of byte arrays
dart/simd128float32_array_test: Skip # compilers not aware of Simd128
dart/simd128float32_test: Skip # compilers not aware of Simd128
-dart/isolate_unhandled*: Skip
[ $compiler == dart2js ]
# The source positions do not match with dart2js.
@@ -47,31 +45,15 @@
# Skip until we stabilize language tests.
*: Skip
-[ $arch == simarm ]
-dart/isolate_mirror_local_test: Skip
-
-[ $arch == simmips || $arch == mips ]
-dart/isolate_mirror_local_test: Pass, Crash
-
[ $arch == mips ]
cc/Sdc1Ldc1: Crash # Illegal instructions
cc/Cop1CvtDL: Crash
cc/Cop1CvtDL_neg: Crash
-[ $compiler == none && $runtime == drt ]
-dart/isolate_mirror_local_test: Skip
-
-[ $compiler == none && $runtime == dartium ]
-dart/isolate_mirror_local_test: Fail # Issue 13719: Please triage this failure.
-
[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
-dart/isolate_mirror_remote_test: Fail # Issue 13921
-dart/isolate_unhandled_exception_test: Fail # Issue 13921
dart/mirrored_compilation_error_test: Skip # Can't pass needed VM flag
[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
dart/optimized_stacktrace_test: StaticWarning
-dart/isolate_mirror_local_test: Fail, OK # API being removed.
-dart/isolate_mirror_remote_test: Fail, OK # API being removed.
dart/mirrored_compilation_error_test: CompileTimeError, OK # This test intentionally includes invalid method bodies.
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index fa0b058..550efdd 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -216,11 +216,7 @@
V(Float32x4_getW, 1) \
V(Float32x4_getSignMask, 1) \
V(Float32x4_shuffle, 2) \
- V(Float32x4_withZWInXY, 2) \
- V(Float32x4_interleaveXY, 2) \
- V(Float32x4_interleaveZW, 2) \
- V(Float32x4_interleaveXYPairs, 2) \
- V(Float32x4_interleaveZWPairs, 2) \
+ V(Float32x4_shuffleMix, 3) \
V(Float32x4_setX, 2) \
V(Float32x4_setY, 2) \
V(Float32x4_setZ, 2) \
@@ -247,6 +243,8 @@
V(Uint32x4_setZ, 2) \
V(Uint32x4_setW, 2) \
V(Uint32x4_getSignMask, 1) \
+ V(Uint32x4_shuffle, 2) \
+ V(Uint32x4_shuffleMix, 3) \
V(Uint32x4_getFlagX, 1) \
V(Uint32x4_getFlagY, 1) \
V(Uint32x4_getFlagZ, 1) \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 22ac5db..4d384a4 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1218,6 +1218,19 @@
getter.set_result_type(type);
cls.AddFunction(getter);
field.set_value(Instance::Handle(Object::sentinel().raw()));
+
+ // Create initializer function.
+ // We don't have the start position of the initializer expression
+ // here, but can compute it from the field identifier position:
+ // The initializer expression starts after the assignment token at +2.
+ const intptr_t initializer_pos = field.token_pos() + 2;
+ const Function& init_function = Function::ZoneHandle(
+ Function::NewStaticInitializer(
+ String::Handle(field.name()),
+ type,
+ cls,
+ initializer_pos));
+ cls.AddFunction(init_function);
}
}
}
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index a3f0c83..ae577df 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1694,31 +1694,6 @@
}
-static intptr_t GetListLength(const Object& value) {
- const intptr_t cid = value.GetClassId();
- ASSERT(RawObject::IsBuiltinListClassId(cid));
- // Extract list length.
- if (value.IsTypedData()) {
- const TypedData& list = TypedData::Cast(value);
- return list.Length();
- } else if (value.IsArray()) {
- const Array& list = Array::Cast(value);
- return list.Length();
- } else if (value.IsGrowableObjectArray()) {
- // List length is variable.
- return Field::kNoFixedLength;
- } else if (value.IsExternalTypedData()) {
- // TODO(johnmccutchan): Enable for external typed data.
- return Field::kNoFixedLength;
- } else if (RawObject::IsTypedDataViewClassId(cid)) {
- // TODO(johnmccutchan): Enable for typed data views.
- return Field::kNoFixedLength;
- }
- UNIMPLEMENTED();
- return Field::kNoFixedLength;
-}
-
-
// Update global type feedback recorded for a field recording the assignment
// of the given value.
// Arg0: Field object;
@@ -1726,14 +1701,7 @@
DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) {
const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
const Object& value = Object::Handle(arguments.ArgAt(1));
- const intptr_t cid = value.GetClassId();
- field.UpdateCid(cid);
- intptr_t list_length = Field::kNoFixedLength;
- if ((field.guarded_cid() != kDynamicCid) &&
- field.is_final() && RawObject::IsBuiltinListClassId(cid)) {
- list_length = GetListLength(value);
- }
- field.UpdateLength(list_length);
+ field.UpdateGuardedCidAndLength(value);
}
} // namespace dart
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 6cbfac4..6e61697 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -892,7 +892,7 @@
const char* kEvalConst = "eval_const";
const Function& func = Function::ZoneHandle(Function::New(
String::Handle(Symbols::New(kEvalConst)),
- RawFunction::kImplicitStaticFinalGetter,
+ RawFunction::kRegularFunction,
true, // static function.
false, // not const function.
false, // not abstract
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index b3b9ce4..5faea45 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1080,8 +1080,7 @@
class_name,
function_name,
kNumArguments,
- Object::empty_array(),
- Resolver::kIsQualified));
+ Object::empty_array()));
ASSERT(!function.IsNull());
const Array& args = Array::Handle(isolate, Array::New(kNumArguments));
args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id)));
@@ -3105,8 +3104,7 @@
Resolver::ResolveStatic(cls,
function_name,
number_of_arguments,
- Object::empty_array(),
- Resolver::kIsQualified));
+ Object::empty_array()));
if (function.IsNull()) {
const String& cls_name = String::Handle(isolate, cls.Name());
return Api::NewError("%s: did not find static method '%s.%s'.",
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 332965e..39e53aa 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -123,9 +123,7 @@
const String& function_name =
String::Handle(core_lib.PrivateName(Symbols::AllocateInvocationMirror()));
const Function& allocation_function = Function::Handle(
- Resolver::ResolveStaticByName(invocation_mirror_class,
- function_name,
- Resolver::kIsQualified));
+ invocation_mirror_class.LookupStaticFunction(function_name));
ASSERT(!allocation_function.IsNull());
const int kNumAllocationArgs = 4;
const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs));
@@ -390,8 +388,7 @@
class_name,
function_name,
kNumArguments,
- Object::empty_array(),
- Resolver::kIsQualified);
+ Object::empty_array());
ASSERT(!function.IsNull());
isolate->object_store()->set_lookup_receive_port_function(function);
}
@@ -422,8 +419,7 @@
class_name,
function_name,
kNumArguments,
- Object::empty_array(),
- Resolver::kIsQualified);
+ Object::empty_array());
ASSERT(!function.IsNull());
isolate->object_store()->set_handle_message_function(function);
}
@@ -457,8 +453,7 @@
class_name,
function_name,
kNumArguments,
- Object::empty_array(),
- Resolver::kIsQualified));
+ Object::empty_array()));
ASSERT(!function.IsNull());
const Array& args = Array::Handle(Array::New(kNumArguments));
args.SetAt(0, Integer::Handle(Integer::New(port_id)));
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 67b1c0de..5e023b4 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1777,6 +1777,7 @@
if ((fkind == RawFunction::kImplicitGetter) ||
(fkind == RawFunction::kImplicitSetter) ||
(fkind == RawFunction::kImplicitStaticFinalGetter) ||
+ (fkind == RawFunction::kStaticInitializer) ||
(fkind == RawFunction::kMethodExtractor) ||
(fkind == RawFunction::kNoSuchMethodDispatcher) ||
(fkind == RawFunction::kInvokeFieldDispatcher)) {
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 53e0394..fb82608 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -27,6 +27,7 @@
DEFINE_FLAG(bool, eliminate_type_checks, true,
"Eliminate type checks when allowed by static type analysis.");
DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree.");
+DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables.");
DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph.");
DEFINE_FLAG(bool, print_flow_graph_optimized, false,
"Print the IR flow graph when optimizing.");
@@ -930,7 +931,8 @@
for_value.value(),
node->type(),
node->dst_name())) {
- checked_value = for_value.value()->definition(); // No check needed.
+ // Drop the value and 0 additional temporaries.
+ checked_value = new DropTempsInstr(0, for_value.value());
} else {
checked_value = BuildAssertAssignable(node->expr()->token_pos(),
for_value.value(),
@@ -1301,12 +1303,17 @@
ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
ValueGraphVisitor for_value(owner(), temp_index());
node->left()->Visit(&for_value);
+ Append(for_value);
const String& dst_name = String::ZoneHandle(
Symbols::New(Exceptions::kCastErrorDstName));
- if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) {
- Append(for_value);
- Do(BuildAssertAssignable(
- node->token_pos(), for_value.value(), type, dst_name));
+ if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) {
+ // Drop the value and 0 additional temporaries.
+ Do(new DropTempsInstr(0, for_value.value()));
+ } else {
+ Do(BuildAssertAssignable(node->token_pos(),
+ for_value.value(),
+ type,
+ dst_name));
}
}
@@ -3716,8 +3723,7 @@
Resolver::ResolveStatic(cls,
Library::PrivateCoreLibName(Symbols::ThrowNew()),
arguments->length(),
- Object::null_array(),
- Resolver::kIsQualified));
+ Object::null_array()));
ASSERT(!func.IsNull());
return new StaticCallInstr(token_pos,
func,
@@ -3800,6 +3806,9 @@
// Print the function ast before IL generation.
AstPrinter::PrintFunctionNodes(*parsed_function());
}
+ if (FLAG_print_scopes) {
+ AstPrinter::PrintFunctionScope(*parsed_function());
+ }
const Function& function = parsed_function()->function();
TargetEntryInstr* normal_entry =
new TargetEntryInstr(AllocateBlockId(),
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 3ce60f9..199b4f3 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -22,7 +22,6 @@
namespace dart {
-DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables.");
DECLARE_FLAG(bool, code_comments);
DECLARE_FLAG(bool, enable_type_checks);
DECLARE_FLAG(bool, intrinsify);
@@ -645,7 +644,7 @@
}
// Even if an intrinsified version of the function was successfully
// generated, it may fall through to the non-intrinsified method body.
- return Intrinsifier::Intrinsify(parsed_function().function(), assembler());
+ Intrinsifier::Intrinsify(parsed_function().function(), assembler());
}
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index a635ad0..244c211 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -24,8 +24,6 @@
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(int, reoptimization_counter_threshold);
-DECLARE_FLAG(bool, print_ast);
-DECLARE_FLAG(bool, print_scopes);
DECLARE_FLAG(bool, enable_type_checks);
DECLARE_FLAG(bool, eliminate_type_checks);
@@ -1007,6 +1005,7 @@
// LR: return address.
// SP: receiver.
// Sequence node has one return node, its input is load field node.
+ __ Comment("Inlined Getter");
__ ldr(R0, Address(SP, 0 * kWordSize));
__ LoadFromOffset(kWord, R0, R0, offset - kHeapObjectTag);
__ Ret();
@@ -1018,6 +1017,7 @@
// SP+1: receiver.
// SP+0: value.
// Sequence node has one store node and one return NULL node.
+ __ Comment("Inlined Setter");
__ ldr(R0, Address(SP, 1 * kWordSize)); // Receiver.
__ ldr(R1, Address(SP, 0 * kWordSize)); // Value.
__ StoreIntoObject(R0, FieldAddress(R0, offset), R1);
@@ -1162,16 +1162,6 @@
}
}
- if (FLAG_print_scopes) {
- // Print the function scope (again) after generating the prologue in order
- // to see annotations such as allocation indices of locals.
- if (FLAG_print_ast) {
- // Second printing.
- OS::Print("Annotated ");
- }
- AstPrinter::PrintFunctionScope(parsed_function());
- }
-
VisitBlocks();
__ bkpt(0);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 74dda26..f97dda7 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -25,8 +25,6 @@
DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(int, reoptimization_counter_threshold);
-DECLARE_FLAG(bool, print_ast);
-DECLARE_FLAG(bool, print_scopes);
DECLARE_FLAG(bool, enable_type_checks);
DECLARE_FLAG(bool, eliminate_type_checks);
DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
@@ -1030,6 +1028,7 @@
// TOS: return address.
// +1 : receiver.
// Sequence node has one return node, its input is load field node.
+ __ Comment("Inlined Getter");
__ movl(EAX, Address(ESP, 1 * kWordSize));
__ movl(EAX, FieldAddress(EAX, offset));
__ ret();
@@ -1041,6 +1040,7 @@
// +1 : value
// +2 : receiver.
// Sequence node has one store node and one return NULL node.
+ __ Comment("Inlined Setter");
__ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver.
__ movl(EBX, Address(ESP, 1 * kWordSize)); // Value.
__ StoreIntoObject(EAX, FieldAddress(EAX, offset), EBX);
@@ -1170,16 +1170,6 @@
}
}
- if (FLAG_print_scopes) {
- // Print the function scope (again) after generating the prologue in order
- // to see annotations such as allocation indices of locals.
- if (FLAG_print_ast) {
- // Second printing.
- OS::Print("Annotated ");
- }
- AstPrinter::PrintFunctionScope(parsed_function());
- }
-
ASSERT(!block_order().is_empty());
VisitBlocks();
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 2cd1ddf..e13470f 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -24,8 +24,6 @@
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(int, reoptimization_counter_threshold);
-DECLARE_FLAG(bool, print_ast);
-DECLARE_FLAG(bool, print_scopes);
DECLARE_FLAG(bool, enable_type_checks);
DECLARE_FLAG(bool, eliminate_type_checks);
@@ -1035,6 +1033,7 @@
// RA: return address.
// SP: receiver.
// Sequence node has one return node, its input is load field node.
+ __ Comment("Inlined Getter");
__ lw(V0, Address(SP, 0 * kWordSize));
__ lw(V0, Address(V0, offset - kHeapObjectTag));
__ Ret();
@@ -1046,6 +1045,7 @@
// SP+1: receiver.
// SP+0: value.
// Sequence node has one store node and one return NULL node.
+ __ Comment("Inlined Setter");
__ lw(T0, Address(SP, 1 * kWordSize)); // Receiver.
__ lw(T1, Address(SP, 0 * kWordSize)); // Value.
__ StoreIntoObject(T0, FieldAddress(T0, offset), T1);
@@ -1203,16 +1203,6 @@
}
}
- if (FLAG_print_scopes) {
- // Print the function scope (again) after generating the prologue in order
- // to see annotations such as allocation indices of locals.
- if (FLAG_print_ast) {
- // Second printing.
- OS::Print("Annotated ");
- }
- AstPrinter::PrintFunctionScope(parsed_function());
- }
-
VisitBlocks();
__ break_(0);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 56f2bc8..9b67e17 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -24,8 +24,6 @@
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(int, reoptimization_counter_threshold);
-DECLARE_FLAG(bool, print_ast);
-DECLARE_FLAG(bool, print_scopes);
DECLARE_FLAG(bool, enable_type_checks);
DECLARE_FLAG(bool, eliminate_type_checks);
@@ -1014,6 +1012,7 @@
// TOS: return address.
// +1 : receiver.
// Sequence node has one return node, its input is load field node.
+ __ Comment("Inlined Getter");
__ movq(RAX, Address(RSP, 1 * kWordSize));
__ movq(RAX, FieldAddress(RAX, offset));
__ ret();
@@ -1025,6 +1024,7 @@
// +1 : value
// +2 : receiver.
// Sequence node has one store node and one return NULL node.
+ __ Comment("Inlined Setter");
__ movq(RAX, Address(RSP, 2 * kWordSize)); // Receiver.
__ movq(RBX, Address(RSP, 1 * kWordSize)); // Value.
__ StoreIntoObject(RAX, FieldAddress(RAX, offset), RBX);
@@ -1201,16 +1201,6 @@
}
}
- if (FLAG_print_scopes) {
- // Print the function scope (again) after generating the prologue in order
- // to see annotations such as allocation indices of locals.
- if (FLAG_print_ast) {
- // Second printing.
- OS::Print("Annotated ");
- }
- AstPrinter::PrintFunctionScope(parsed_function());
- }
-
ASSERT(!block_order().is_empty());
VisitBlocks();
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index bf34043..79fcd02 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -1460,14 +1460,18 @@
}
+static uint16_t ClampUint16(intptr_t v) {
+ return (v > 0xFFFF) ? 0xFFFF : static_cast<uint16_t>(v);
+}
+
+
void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph) {
GraphInfoCollector info;
info.Collect(*flow_graph);
const Function& function = flow_graph->parsed_function().function();
function.set_optimized_instruction_count(
- static_cast<uint16_t>(info.instruction_count()));
- function.set_optimized_call_site_count(
- static_cast<uint16_t>(info.call_site_count()));
+ ClampUint16(info.instruction_count()));
+ function.set_optimized_call_site_count(ClampUint16(info.call_site_count()));
}
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 78815e2..cda4032 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1692,24 +1692,30 @@
call->env(),
call);
intptr_t mask = 0;
- if (getter == MethodRecognizer::kFloat32x4Shuffle) {
+ if ((getter == MethodRecognizer::kFloat32x4Shuffle) ||
+ (getter == MethodRecognizer::kFloat32x4ShuffleMix)) {
// Extract shuffle mask.
- ASSERT(call->ArgumentCount() == 2);
- Definition* mask_definition = call->ArgumentAt(1);
+ Definition* mask_definition = NULL;
+ if (getter == MethodRecognizer::kFloat32x4Shuffle) {
+ ASSERT(call->ArgumentCount() == 2);
+ mask_definition = call->ArgumentAt(1);
+ } else {
+ ASSERT(getter == MethodRecognizer::kFloat32x4ShuffleMix);
+ ASSERT(call->ArgumentCount() == 3);
+ mask_definition = call->ArgumentAt(2);
+ }
if (!mask_definition->IsConstant()) {
- // Not a constant.
return false;
}
ASSERT(mask_definition->IsConstant());
ConstantInstr* constant_instruction = mask_definition->AsConstant();
const Object& constant_mask = constant_instruction->value();
if (!constant_mask.IsSmi()) {
- // Not a smi.
return false;
}
ASSERT(constant_mask.IsSmi());
mask = Smi::Cast(constant_mask).Value();
- if (mask < 0 || mask > 255) {
+ if ((mask < 0) || (mask > 255)) {
// Not a valid mask.
return false;
}
@@ -1721,13 +1727,22 @@
call->deopt_id());
ReplaceCall(call, instr);
return true;
+ } else if (getter == MethodRecognizer::kFloat32x4ShuffleMix) {
+ Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr(
+ getter,
+ new Value(call->ArgumentAt(0)),
+ new Value(call->ArgumentAt(1)),
+ mask,
+ call->deopt_id());
+ ReplaceCall(call, instr);
+ return true;
} else {
ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle) ||
(getter == MethodRecognizer::kFloat32x4ShuffleX) ||
(getter == MethodRecognizer::kFloat32x4ShuffleY) ||
(getter == MethodRecognizer::kFloat32x4ShuffleZ) ||
(getter == MethodRecognizer::kFloat32x4ShuffleW));
- Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr(
+ Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr(
getter,
new Value(call->ArgumentAt(0)),
mask,
@@ -1751,6 +1766,35 @@
call->deopt_id(),
call->env(),
call);
+ intptr_t mask = 0;
+ if ((getter == MethodRecognizer::kUint32x4Shuffle) ||
+ (getter == MethodRecognizer::kUint32x4ShuffleMix)) {
+ // Extract shuffle mask.
+ Definition* mask_definition = NULL;
+ if (getter == MethodRecognizer::kUint32x4Shuffle) {
+ ASSERT(call->ArgumentCount() == 2);
+ mask_definition = call->ArgumentAt(1);
+ } else {
+ ASSERT(getter == MethodRecognizer::kUint32x4ShuffleMix);
+ ASSERT(call->ArgumentCount() == 3);
+ mask_definition = call->ArgumentAt(2);
+ }
+ if (!mask_definition->IsConstant()) {
+ return false;
+ }
+ ASSERT(mask_definition->IsConstant());
+ ConstantInstr* constant_instruction = mask_definition->AsConstant();
+ const Object& constant_mask = constant_instruction->value();
+ if (!constant_mask.IsSmi()) {
+ return false;
+ }
+ ASSERT(constant_mask.IsSmi());
+ mask = Smi::Cast(constant_mask).Value();
+ if ((mask < 0) || (mask > 255)) {
+ // Not a valid mask.
+ return false;
+ }
+ }
if (getter == MethodRecognizer::kUint32x4GetSignMask) {
Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr(
getter,
@@ -1758,6 +1802,23 @@
call->deopt_id());
ReplaceCall(call, instr);
return true;
+ } else if (getter == MethodRecognizer::kUint32x4ShuffleMix) {
+ Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr(
+ getter,
+ new Value(call->ArgumentAt(0)),
+ new Value(call->ArgumentAt(1)),
+ mask,
+ call->deopt_id());
+ ReplaceCall(call, instr);
+ return true;
+ } else if (getter == MethodRecognizer::kUint32x4Shuffle) {
+ Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr(
+ getter,
+ new Value(call->ArgumentAt(0)),
+ mask,
+ call->deopt_id());
+ ReplaceCall(call, instr);
+ return true;
} else {
Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr(
getter,
@@ -2320,26 +2381,6 @@
ReplaceCall(call, minmax);
return true;
}
- case MethodRecognizer::kFloat32x4WithZWInXY:
- case MethodRecognizer::kFloat32x4InterleaveXY:
- case MethodRecognizer::kFloat32x4InterleaveZW:
- case MethodRecognizer::kFloat32x4InterleaveXYPairs:
- case MethodRecognizer::kFloat32x4InterleaveZWPairs: {
- Definition* left = call->ArgumentAt(0);
- Definition* right = call->ArgumentAt(1);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
- Float32x4TwoArgShuffleInstr* two_arg_shuffle =
- new Float32x4TwoArgShuffleInstr(recognized_kind, new Value(left),
- new Value(right), call->deopt_id());
- ReplaceCall(call, two_arg_shuffle);
- return true;
- }
case MethodRecognizer::kFloat32x4Scale: {
Definition* left = call->ArgumentAt(0);
Definition* right = call->ArgumentAt(1);
@@ -2429,6 +2470,7 @@
ReplaceCall(call, clamp);
return true;
}
+ case MethodRecognizer::kFloat32x4ShuffleMix:
case MethodRecognizer::kFloat32x4Shuffle: {
return InlineFloat32x4Getter(call, recognized_kind);
}
@@ -2446,6 +2488,8 @@
}
ASSERT(call->HasICData());
switch (recognized_kind) {
+ case MethodRecognizer::kUint32x4ShuffleMix:
+ case MethodRecognizer::kUint32x4Shuffle:
case MethodRecognizer::kUint32x4GetFlagX:
case MethodRecognizer::kUint32x4GetFlagY:
case MethodRecognizer::kUint32x4GetFlagZ:
@@ -4194,10 +4238,20 @@
}
+// Load instructions handled by load elimination.
+static bool IsCandidateLoad(Instruction* instr) {
+ return instr->IsLoadField()
+ || instr->IsLoadIndexed()
+ || instr->IsLoadStaticField()
+ || instr->IsCurrentContext();
+}
+
+
static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets,
intptr_t loop_header_index,
Instruction* instr) {
- return (sets != NULL) &&
+ return IsCandidateLoad(instr) &&
+ (sets != NULL) &&
instr->HasPlaceId() &&
((*sets)[loop_header_index] != NULL) &&
(*sets)[loop_header_index]->Contains(instr->place_id());
@@ -6482,6 +6536,8 @@
ASSERT(field.is_static());
if (field.is_final()) {
Instance& obj = Instance::Handle(field.value());
+ ASSERT(obj.raw() != Object::sentinel().raw());
+ ASSERT(obj.raw() != Object::transition_sentinel().raw());
if (obj.IsSmi() || obj.IsOld()) {
SetValue(instr, obj);
return;
@@ -6873,7 +6929,13 @@
}
-void ConstantPropagator::VisitFloat32x4Shuffle(Float32x4ShuffleInstr* instr) {
+void ConstantPropagator::VisitSimd32x4Shuffle(Simd32x4ShuffleInstr* instr) {
+ SetValue(instr, non_constant_);
+}
+
+
+void ConstantPropagator::VisitSimd32x4ShuffleMix(
+ Simd32x4ShuffleMixInstr* instr) {
SetValue(instr, non_constant_);
}
@@ -6936,12 +6998,6 @@
}
-void ConstantPropagator::VisitFloat32x4TwoArgShuffle(
- Float32x4TwoArgShuffleInstr* instr) {
- SetValue(instr, non_constant_);
-}
-
-
void ConstantPropagator::VisitUint32x4BoolConstructor(
Uint32x4BoolConstructorInstr* instr) {
SetValue(instr, non_constant_);
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 791d97a..6dc3a61 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -1049,13 +1049,26 @@
}
-CompileType Float32x4ShuffleInstr::ComputeType() const {
+CompileType Simd32x4ShuffleInstr::ComputeType() const {
if ((op_kind() == MethodRecognizer::kFloat32x4ShuffleX) ||
(op_kind() == MethodRecognizer::kFloat32x4ShuffleY) ||
(op_kind() == MethodRecognizer::kFloat32x4ShuffleZ) ||
(op_kind() == MethodRecognizer::kFloat32x4ShuffleW)) {
return CompileType::FromCid(kDoubleCid);
}
+ if ((op_kind() == MethodRecognizer::kUint32x4Shuffle)) {
+ return CompileType::FromCid(kUint32x4Cid);
+ }
+ ASSERT((op_kind() == MethodRecognizer::kFloat32x4Shuffle));
+ return CompileType::FromCid(kFloat32x4Cid);
+}
+
+
+CompileType Simd32x4ShuffleMixInstr::ComputeType() const {
+ if (op_kind() == MethodRecognizer::kUint32x4ShuffleMix) {
+ return CompileType::FromCid(kUint32x4Cid);
+ }
+ ASSERT((op_kind() == MethodRecognizer::kFloat32x4ShuffleMix));
return CompileType::FromCid(kFloat32x4Cid);
}
@@ -1120,11 +1133,6 @@
}
-CompileType Float32x4TwoArgShuffleInstr::ComputeType() const {
- return CompileType::FromCid(kFloat32x4Cid);
-}
-
-
CompileType Uint32x4BoolConstructorInstr::ComputeType() const {
return CompileType::FromCid(kUint32x4Cid);
}
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index d0587ff..cfeca9b 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -607,12 +607,19 @@
}
-void Float32x4ShuffleInstr::PrintOperandsTo(BufferFormatter* f) const {
+void Simd32x4ShuffleInstr::PrintOperandsTo(BufferFormatter* f) const {
// TODO(johnmccutchan): Add proper string enumeration of shuffle.
- f->Print("SHUFFLE ");
+ f->Print("%s, ", MethodRecognizer::KindToCString(op_kind()));
value()->PrintTo(f);
}
+void Simd32x4ShuffleMixInstr::PrintOperandsTo(BufferFormatter* f) const {
+ f->Print("%s, ", MethodRecognizer::KindToCString(op_kind()));
+ xy()->PrintTo(f);
+ f->Print(", ");
+ zw()->PrintTo(f);
+}
+
void Simd32x4GetSignMaskInstr::PrintOperandsTo(BufferFormatter* f) const {
if (op_kind() == MethodRecognizer::kFloat32x4GetSignMask) {
@@ -706,12 +713,7 @@
}
-void Float32x4TwoArgShuffleInstr::PrintOperandsTo(BufferFormatter* f) const {
- f->Print("%s, ", MethodRecognizer::KindToCString(op_kind()));
- left()->PrintTo(f);
- f->Print(", ");
- right()->PrintTo(f);
-}
+
void Uint32x4BoolConstructorInstr::PrintOperandsTo(BufferFormatter* f) const {
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 2da67b0..50e3caf 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -425,7 +425,7 @@
ASSERT(function.CheckSourceFingerprint(fp)); \
return true; \
}
-POLYMORPHC_TARGET_LIST(RECOGNIZE_FUNCTION)
+POLYMORPHIC_TARGET_LIST(RECOGNIZE_FUNCTION)
#undef RECOGNIZE_FUNCTION
return false;
}
@@ -2721,8 +2721,7 @@
cls,
Library::PrivateCoreLibName(Symbols::Interpolate()),
kNumberOfArguments,
- kNoArgumentNames,
- Resolver::kIsQualified);
+ kNoArgumentNames);
}
ASSERT(!function_.IsNull());
return function_;
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 53e8e49..b4e6878 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -95,6 +95,7 @@
V(Float32x4, Float32x4.fromUint32x4Bits, Float32x4FromUint32x4Bits, \
770033146) \
V(_Float32x4, shuffle, Float32x4Shuffle, 1178727105) \
+ V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 927956119) \
V(_Float32x4, get:x, Float32x4ShuffleX, 1351717838) \
V(_Float32x4, get:y, Float32x4ShuffleY, 217386410) \
V(_Float32x4, get:z, Float32x4ShuffleZ, 2144923721) \
@@ -119,11 +120,6 @@
V(_Float32x4, withY, Float32x4WithY, 1806065938) \
V(_Float32x4, withZ, Float32x4WithZ, 320659034) \
V(_Float32x4, withW, Float32x4WithW, 1108437255) \
- V(_Float32x4, withZWInXY, Float32x4WithZWInXY, 1198101679) \
- V(_Float32x4, interleaveXY, Float32x4InterleaveXY, 2001324072) \
- V(_Float32x4, interleaveZW, Float32x4InterleaveZW, 928280031) \
- V(_Float32x4, interleaveXYPairs, Float32x4InterleaveXYPairs, 1046078993) \
- V(_Float32x4, interleaveZWPairs, Float32x4InterleaveZWPairs, 1001751955) \
V(Uint32x4, Uint32x4.bool, Uint32x4BoolConstructor, 517444095) \
V(Uint32x4, Uint32x4.fromFloat32x4Bits, Uint32x4FromFloat32x4Bits, \
1080034855) \
@@ -132,6 +128,8 @@
V(_Uint32x4, get:flagZ, Uint32x4GetFlagZ, 944733935) \
V(_Uint32x4, get:flagW, Uint32x4GetFlagW, 22746169) \
V(_Uint32x4, get:signMask, Uint32x4GetSignMask, 1858144083) \
+ V(_Uint32x4, shuffle, Uint32x4Shuffle, 146209630) \
+ V(_Uint32x4, shuffleMix, Uint32x4ShuffleMix, 1251494596) \
V(_Uint32x4, select, Uint32x4Select, 72244182) \
V(_Uint32x4, withFlagX, Uint32x4WithFlagX, 1475542073) \
V(_Uint32x4, withFlagY, Uint32x4WithFlagY, 830610988) \
@@ -184,7 +182,7 @@
V(_GrowableList, forEach, GrowableArrayForEach, 1675430533) \
// A list of core functions that internally dispatch based on received id.
-#define POLYMORPHC_TARGET_LIST(V) \
+#define POLYMORPHIC_TARGET_LIST(V) \
V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 272598802) \
V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 831354841) \
V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 1832126257) \
@@ -194,7 +192,7 @@
V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 185163470) \
V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1356392173) \
V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1239681356) \
- V(_TypedList, _getUint32x4, ByteArrayBaseGetUint32x4, 1239681356) \
+ V(_TypedList, _getUint32x4, ByteArrayBaseGetUint32x4, 1499091330) \
// Class that recognizes the name and owner of a function and returns the
// corresponding enum. See RECOGNIZED_LIST above for list of recognizable
@@ -677,7 +675,8 @@
M(GuardField) \
M(IfThenElse) \
M(BinaryFloat32x4Op) \
- M(Float32x4Shuffle) \
+ M(Simd32x4Shuffle) \
+ M(Simd32x4ShuffleMix) \
M(Simd32x4GetSignMask) \
M(Float32x4Constructor) \
M(Float32x4Zero) \
@@ -690,7 +689,6 @@
M(Float32x4Clamp) \
M(Float32x4With) \
M(Float32x4ToUint32x4) \
- M(Float32x4TwoArgShuffle) \
M(MaterializeObject) \
M(Uint32x4BoolConstructor) \
M(Uint32x4GetFlag) \
@@ -967,7 +965,8 @@
friend class BinaryFloat32x4OpInstr;
friend class Float32x4ZeroInstr;
friend class Float32x4SplatInstr;
- friend class Float32x4ShuffleInstr;
+ friend class Simd32x4ShuffleInstr;
+ friend class Simd32x4ShuffleMixInstr;
friend class Simd32x4GetSignMaskInstr;
friend class Float32x4ConstructorInstr;
friend class Float32x4ComparisonInstr;
@@ -978,7 +977,6 @@
friend class Float32x4ClampInstr;
friend class Float32x4WithInstr;
friend class Float32x4ToUint32x4Instr;
- friend class Float32x4TwoArgShuffleInstr;
friend class Uint32x4BoolConstructorInstr;
friend class Uint32x4GetFlagInstr;
friend class Uint32x4SetFlagInstr;
@@ -4996,11 +4994,11 @@
};
-class Float32x4ShuffleInstr : public TemplateDefinition<1> {
+class Simd32x4ShuffleInstr : public TemplateDefinition<1> {
public:
- Float32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value,
- intptr_t mask,
- intptr_t deopt_id)
+ Simd32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value,
+ intptr_t mask,
+ intptr_t deopt_id)
: op_kind_(op_kind), mask_(mask) {
SetInputAt(0, value);
deopt_id_ = deopt_id;
@@ -5023,11 +5021,88 @@
(op_kind_ == MethodRecognizer::kFloat32x4ShuffleW)) {
return kUnboxedDouble;
}
+ if ((op_kind_ == MethodRecognizer::kUint32x4Shuffle)) {
+ return kUnboxedUint32x4;
+ }
+ ASSERT((op_kind_ == MethodRecognizer::kFloat32x4Shuffle));
return kUnboxedFloat32x4;
}
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT(idx == 0);
+ if ((op_kind_ == MethodRecognizer::kFloat32x4ShuffleX) ||
+ (op_kind_ == MethodRecognizer::kFloat32x4ShuffleY) ||
+ (op_kind_ == MethodRecognizer::kFloat32x4ShuffleZ) ||
+ (op_kind_ == MethodRecognizer::kFloat32x4ShuffleW) ||
+ (op_kind_ == MethodRecognizer::kFloat32x4Shuffle)) {
+ return kUnboxedFloat32x4;
+ }
+ ASSERT((op_kind_ == MethodRecognizer::kUint32x4Shuffle));
+ return kUnboxedUint32x4;
+ }
+
+ virtual intptr_t DeoptimizationTarget() const {
+ // Direct access since this instruction cannot deoptimize, and the deopt-id
+ // was inherited from another instruction that could deoptimize.
+ return deopt_id_;
+ }
+
+ DECLARE_INSTRUCTION(Simd32x4Shuffle)
+ virtual CompileType ComputeType() const;
+
+ virtual bool AllowsCSE() const { return true; }
+ virtual EffectSet Effects() const { return EffectSet::None(); }
+ virtual EffectSet Dependencies() const { return EffectSet::None(); }
+ virtual bool AttributesEqual(Instruction* other) const {
+ return (op_kind() == other->AsSimd32x4Shuffle()->op_kind()) &&
+ (mask() == other->AsSimd32x4Shuffle()->mask());
+ }
+
+ virtual bool MayThrow() const { return false; }
+
+ private:
+ const MethodRecognizer::Kind op_kind_;
+ const intptr_t mask_;
+
+ DISALLOW_COPY_AND_ASSIGN(Simd32x4ShuffleInstr);
+};
+
+
+class Simd32x4ShuffleMixInstr : public TemplateDefinition<2> {
+ public:
+ Simd32x4ShuffleMixInstr(MethodRecognizer::Kind op_kind, Value* xy,
+ Value* zw, intptr_t mask, intptr_t deopt_id)
+ : op_kind_(op_kind), mask_(mask) {
+ SetInputAt(0, xy);
+ SetInputAt(1, zw);
+ deopt_id_ = deopt_id;
+ }
+
+ Value* xy() const { return inputs_[0]; }
+ Value* zw() const { return inputs_[1]; }
+
+ MethodRecognizer::Kind op_kind() const { return op_kind_; }
+
+ intptr_t mask() const { return mask_; }
+
+ virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+ virtual bool CanDeoptimize() const { return false; }
+
+ virtual Representation representation() const {
+ if (op_kind() == MethodRecognizer::kUint32x4ShuffleMix) {
+ return kUnboxedUint32x4;
+ }
+ ASSERT(op_kind() == MethodRecognizer::kFloat32x4ShuffleMix);
+ return kUnboxedFloat32x4;
+ }
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+ ASSERT((idx == 0) || (idx == 1));
+ if (op_kind() == MethodRecognizer::kUint32x4ShuffleMix) {
+ return kUnboxedUint32x4;
+ }
+ ASSERT(op_kind() == MethodRecognizer::kFloat32x4ShuffleMix);
return kUnboxedFloat32x4;
}
@@ -5037,15 +5112,15 @@
return deopt_id_;
}
- DECLARE_INSTRUCTION(Float32x4Shuffle)
+ DECLARE_INSTRUCTION(Simd32x4ShuffleMix)
virtual CompileType ComputeType() const;
virtual bool AllowsCSE() const { return true; }
virtual EffectSet Effects() const { return EffectSet::None(); }
virtual EffectSet Dependencies() const { return EffectSet::None(); }
virtual bool AttributesEqual(Instruction* other) const {
- return op_kind() == other->AsFloat32x4Shuffle()->op_kind() &&
- mask() == other->AsFloat32x4Shuffle()->mask();
+ return (op_kind() == other->AsSimd32x4ShuffleMix()->op_kind()) &&
+ (mask() == other->AsSimd32x4ShuffleMix()->mask());
}
virtual bool MayThrow() const { return false; }
@@ -5054,7 +5129,7 @@
const MethodRecognizer::Kind op_kind_;
const intptr_t mask_;
- DISALLOW_COPY_AND_ASSIGN(Float32x4ShuffleInstr);
+ DISALLOW_COPY_AND_ASSIGN(Simd32x4ShuffleMixInstr);
};
@@ -5757,59 +5832,6 @@
};
-class Float32x4TwoArgShuffleInstr : public TemplateDefinition<2> {
- public:
- Float32x4TwoArgShuffleInstr(MethodRecognizer::Kind op_kind, Value* left,
- Value* right, intptr_t deopt_id)
- : op_kind_(op_kind) {
- SetInputAt(0, left);
- SetInputAt(1, right);
- deopt_id_ = deopt_id;
- }
-
- Value* left() const { return inputs_[0]; }
- Value* right() const { return inputs_[1]; }
-
- MethodRecognizer::Kind op_kind() const { return op_kind_; }
-
- virtual void PrintOperandsTo(BufferFormatter* f) const;
-
- virtual bool CanDeoptimize() const { return false; }
-
- virtual Representation representation() const {
- return kUnboxedFloat32x4;
- }
-
- virtual Representation RequiredInputRepresentation(intptr_t idx) const {
- ASSERT((idx == 0) || (idx == 1));
- return kUnboxedFloat32x4;
- }
-
- virtual intptr_t DeoptimizationTarget() const {
- // Direct access since this instruction cannot deoptimize, and the deopt-id
- // was inherited from another instruction that could deoptimize.
- return deopt_id_;
- }
-
- DECLARE_INSTRUCTION(Float32x4TwoArgShuffle)
- virtual CompileType ComputeType() const;
-
- virtual bool AllowsCSE() const { return true; }
- virtual EffectSet Effects() const { return EffectSet::None(); }
- virtual EffectSet Dependencies() const { return EffectSet::None(); }
- virtual bool AttributesEqual(Instruction* other) const {
- return op_kind() == other->AsFloat32x4TwoArgShuffle()->op_kind();
- }
-
- virtual bool MayThrow() const { return false; }
-
- private:
- const MethodRecognizer::Kind op_kind_;
-
- DISALLOW_COPY_AND_ASSIGN(Float32x4TwoArgShuffleInstr);
-};
-
-
class Uint32x4SelectInstr : public TemplateDefinition<3> {
public:
Uint32x4SelectInstr(Value* mask, Value* trueValue, Value* falseValue,
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index e9d032e..3c613e8 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -3043,7 +3043,7 @@
}
-LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;
LocationSummary* summary =
@@ -3055,7 +3055,7 @@
}
-void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
QRegister value = locs()->in(0).fpu_reg();
QRegister result = locs()->out().fpu_reg();
DRegister dresult0 = EvenDRegisterOf(result);
@@ -3073,6 +3073,7 @@
// For some cases the vdup instruction requires fewer
// instructions. For arbitrary shuffles, use vtbl.
+
switch (op_kind()) {
case MethodRecognizer::kFloat32x4ShuffleX:
__ vdup(kWord, result, dvalue0, 0);
@@ -3090,6 +3091,7 @@
__ vdup(kWord, result, dvalue1, 1);
__ vcvtds(dresult0, sresult0);
break;
+ case MethodRecognizer::kUint32x4Shuffle:
case MethodRecognizer::kFloat32x4Shuffle:
if (mask_ == 0x00) {
__ vdup(kWord, result, dvalue0, 0);
@@ -3100,6 +3102,8 @@
} else if (mask_ == 0xFF) {
__ vdup(kWord, result, dvalue1, 1);
} else {
+ // TODO(zra): Investigate better instruction sequences for other
+ // shuffle masks.
SRegister svalues[4];
svalues[0] = EvenSRegisterOf(dtemp0);
@@ -3119,6 +3123,62 @@
}
+LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const {
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions.
+ summary->set_in(0, Location::FpuRegisterLocation(Q4));
+ summary->set_in(1, Location::FpuRegisterLocation(Q5));
+ summary->set_out(Location::FpuRegisterLocation(Q6));
+ return summary;
+}
+
+
+void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ QRegister left = locs()->in(0).fpu_reg();
+ QRegister right = locs()->in(1).fpu_reg();
+ QRegister result = locs()->out().fpu_reg();
+
+ DRegister dresult0 = EvenDRegisterOf(result);
+ DRegister dresult1 = OddDRegisterOf(result);
+ SRegister sresult0 = EvenSRegisterOf(dresult0);
+ SRegister sresult1 = OddSRegisterOf(dresult0);
+ SRegister sresult2 = EvenSRegisterOf(dresult1);
+ SRegister sresult3 = OddSRegisterOf(dresult1);
+
+ DRegister dleft0 = EvenDRegisterOf(left);
+ DRegister dleft1 = OddDRegisterOf(left);
+ DRegister dright0 = EvenDRegisterOf(right);
+ DRegister dright1 = OddDRegisterOf(right);
+
+ switch (op_kind()) {
+ case MethodRecognizer::kFloat32x4ShuffleMix:
+ case MethodRecognizer::kUint32x4ShuffleMix:
+ // TODO(zra): Investigate better instruction sequences for shuffle masks.
+ SRegister left_svalues[4];
+ SRegister right_svalues[4];
+
+ left_svalues[0] = EvenSRegisterOf(dleft0);
+ left_svalues[1] = OddSRegisterOf(dleft0);
+ left_svalues[2] = EvenSRegisterOf(dleft1);
+ left_svalues[3] = OddSRegisterOf(dleft1);
+ right_svalues[0] = EvenSRegisterOf(dright0);
+ right_svalues[1] = OddSRegisterOf(dright0);
+ right_svalues[2] = EvenSRegisterOf(dright1);
+ right_svalues[3] = OddSRegisterOf(dright1);
+
+ __ vmovs(sresult0, left_svalues[mask_ & 0x3]);
+ __ vmovs(sresult1, left_svalues[(mask_ >> 2) & 0x3]);
+ __ vmovs(sresult2, right_svalues[(mask_ >> 4) & 0x3]);
+ __ vmovs(sresult3, right_svalues[(mask_ >> 6) & 0x3]);
+ break;
+ default: UNREACHABLE();
+ }
+}
+
+
LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 1;
@@ -3485,56 +3545,6 @@
}
-LocationSummary* Float32x4TwoArgShuffleInstr::MakeLocationSummary() const {
- const intptr_t kNumInputs = 2;
- const intptr_t kNumTemps = 0;
- LocationSummary* summary =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresFpuRegister());
- summary->set_in(1, Location::RequiresFpuRegister());
- summary->set_out(Location::SameAsFirstInput());
- return summary;
-}
-
-
-void Float32x4TwoArgShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- QRegister left = locs()->in(0).fpu_reg();
- QRegister right = locs()->in(1).fpu_reg();
- QRegister result = locs()->out().fpu_reg();
-
- ASSERT(result == left);
-
- DRegister dleft0 = EvenDRegisterOf(left);
- DRegister dleft1 = OddDRegisterOf(left);
- DRegister dright0 = EvenDRegisterOf(right);
- DRegister dright1 = OddDRegisterOf(right);
-
- switch (op_kind()) {
- case MethodRecognizer::kFloat32x4WithZWInXY:
- __ vmovd(dleft0, dright1);
- break;
- case MethodRecognizer::kFloat32x4InterleaveXY:
- __ vmovq(QTMP, right);
- __ vzipqw(left, QTMP);
- break;
- case MethodRecognizer::kFloat32x4InterleaveZW:
- __ vmovq(QTMP, right);
- __ vzipqw(left, QTMP);
- __ vmovq(left, QTMP);
- break;
- case MethodRecognizer::kFloat32x4InterleaveXYPairs:
- __ vmovd(dleft1, dright0);
- break;
- case MethodRecognizer::kFloat32x4InterleaveZWPairs:
- __ vmovq(QTMP, right);
- __ vmovd(EvenDRegisterOf(QTMP), dleft1);
- __ vmovq(result, QTMP);
- break;
- default: UNREACHABLE();
- }
-}
-
-
LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 4;
const intptr_t kNumTemps = 1;
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index b2c3e55..ba97036 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -3135,7 +3135,7 @@
}
-LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;
LocationSummary* summary =
@@ -3146,7 +3146,7 @@
}
-void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
XmmRegister value = locs()->in(0).fpu_reg();
ASSERT(locs()->out().fpu_reg() == value);
@@ -3169,6 +3169,7 @@
__ cvtss2sd(value, value);
break;
case MethodRecognizer::kFloat32x4Shuffle:
+ case MethodRecognizer::kUint32x4Shuffle:
__ shufps(value, value, Immediate(mask_));
break;
default: UNREACHABLE();
@@ -3176,6 +3177,33 @@
}
+LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const {
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_in(1, Location::RequiresFpuRegister());
+ summary->set_out(Location::SameAsFirstInput());
+ return summary;
+}
+
+
+void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ XmmRegister left = locs()->in(0).fpu_reg();
+ XmmRegister right = locs()->in(1).fpu_reg();
+
+ ASSERT(locs()->out().fpu_reg() == left);
+ switch (op_kind()) {
+ case MethodRecognizer::kFloat32x4ShuffleMix:
+ case MethodRecognizer::kUint32x4ShuffleMix:
+ __ shufps(left, right, Immediate(mask_));
+ break;
+ default: UNREACHABLE();
+ }
+}
+
+
LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;
@@ -3537,45 +3565,6 @@
}
-LocationSummary* Float32x4TwoArgShuffleInstr::MakeLocationSummary() const {
- const intptr_t kNumInputs = 2;
- const intptr_t kNumTemps = 0;
- LocationSummary* summary =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresFpuRegister());
- summary->set_in(1, Location::RequiresFpuRegister());
- summary->set_out(Location::SameAsFirstInput());
- return summary;
-}
-
-
-void Float32x4TwoArgShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- XmmRegister left = locs()->in(0).fpu_reg();
- XmmRegister right = locs()->in(1).fpu_reg();
-
- ASSERT(locs()->out().fpu_reg() == left);
-
- switch (op_kind()) {
- case MethodRecognizer::kFloat32x4WithZWInXY:
- __ movhlps(left, right);
- break;
- case MethodRecognizer::kFloat32x4InterleaveXY:
- __ unpcklps(left, right);
- break;
- case MethodRecognizer::kFloat32x4InterleaveZW:
- __ unpckhps(left, right);
- break;
- case MethodRecognizer::kFloat32x4InterleaveXYPairs:
- __ unpcklpd(left, right);
- break;
- case MethodRecognizer::kFloat32x4InterleaveZWPairs:
- __ unpckhpd(left, right);
- break;
- default: UNREACHABLE();
- }
-}
-
-
LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 4;
const intptr_t kNumTemps = 0;
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 636dbf5..ae873ee 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -2969,13 +2969,25 @@
}
-LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const {
UNIMPLEMENTED();
return NULL;
}
-void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNIMPLEMENTED();
+}
+
+
+
+LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const {
+ UNIMPLEMENTED();
+ return NULL;
+}
+
+
+void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
UNIMPLEMENTED();
}
@@ -3101,17 +3113,6 @@
}
-LocationSummary* Float32x4TwoArgShuffleInstr::MakeLocationSummary() const {
- UNIMPLEMENTED();
- return NULL;
-}
-
-
-void Float32x4TwoArgShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
-}
-
-
LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const {
UNIMPLEMENTED();
return NULL;
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 574c51a..fcf2db7 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -3151,7 +3151,7 @@
}
-LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;
LocationSummary* summary =
@@ -3162,7 +3162,7 @@
}
-void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
XmmRegister value = locs()->in(0).fpu_reg();
ASSERT(locs()->out().fpu_reg() == value);
@@ -3185,6 +3185,7 @@
__ cvtss2sd(value, value);
break;
case MethodRecognizer::kFloat32x4Shuffle:
+ case MethodRecognizer::kUint32x4Shuffle:
__ shufps(value, value, Immediate(mask_));
break;
default: UNREACHABLE();
@@ -3192,6 +3193,33 @@
}
+LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const {
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_in(1, Location::RequiresFpuRegister());
+ summary->set_out(Location::SameAsFirstInput());
+ return summary;
+}
+
+
+void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ XmmRegister left = locs()->in(0).fpu_reg();
+ XmmRegister right = locs()->in(1).fpu_reg();
+
+ ASSERT(locs()->out().fpu_reg() == left);
+ switch (op_kind()) {
+ case MethodRecognizer::kFloat32x4ShuffleMix:
+ case MethodRecognizer::kUint32x4ShuffleMix:
+ __ shufps(left, right, Immediate(mask_));
+ break;
+ default: UNREACHABLE();
+ }
+}
+
+
LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;
@@ -3553,45 +3581,6 @@
}
-LocationSummary* Float32x4TwoArgShuffleInstr::MakeLocationSummary() const {
- const intptr_t kNumInputs = 2;
- const intptr_t kNumTemps = 0;
- LocationSummary* summary =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresFpuRegister());
- summary->set_in(1, Location::RequiresFpuRegister());
- summary->set_out(Location::SameAsFirstInput());
- return summary;
-}
-
-
-void Float32x4TwoArgShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- XmmRegister left = locs()->in(0).fpu_reg();
- XmmRegister right = locs()->in(1).fpu_reg();
-
- ASSERT(locs()->out().fpu_reg() == left);
-
- switch (op_kind()) {
- case MethodRecognizer::kFloat32x4WithZWInXY:
- __ movhlps(left, right);
- break;
- case MethodRecognizer::kFloat32x4InterleaveXY:
- __ unpcklps(left, right);
- break;
- case MethodRecognizer::kFloat32x4InterleaveZW:
- __ unpckhps(left, right);
- break;
- case MethodRecognizer::kFloat32x4InterleaveXYPairs:
- __ unpcklpd(left, right);
- break;
- case MethodRecognizer::kFloat32x4InterleaveZWPairs:
- __ unpckhpd(left, right);
- break;
- default: UNREACHABLE();
- }
-}
-
-
LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 4;
const intptr_t kNumTemps = 1;
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index fa3992b..a405284 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
// Class for intrinsifying functions.
+#include "vm/assembler.h"
#include "vm/intrinsifier.h"
#include "vm/flags.h"
#include "vm/object.h"
@@ -154,7 +155,9 @@
class_name, function_name, \
#test_class_name, #test_function_name)) { \
ASSERT(function.CheckSourceFingerprint(fp)); \
- return destination(assembler); \
+ assembler->Comment("Intrinsic"); \
+ destination(assembler); \
+ return; \
} \
if (lib.raw() == Library::CoreLibrary()) {
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index bae81da..63ccb89 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -1575,7 +1575,7 @@
}
-// Arg0: Onebyte String
+// Arg0: OneByteString (receiver).
// Arg1: Start index as Smi.
// Arg2: End index as Smi.
// The indexes must be valid.
@@ -1587,6 +1587,10 @@
__ ldr(R2, Address(SP, kEndIndexOffset));
__ ldr(TMP, Address(SP, kStartIndexOffset));
+ __ orr(R3, R2, ShifterOperand(TMP));
+ __ tst(R3, ShifterOperand(kSmiTagMask));
+ __ b(&fall_through, NE); // 'start', 'end' not Smi.
+
__ sub(R2, R2, ShifterOperand(TMP));
TryAllocateOnebyteString(assembler, &ok, &fall_through);
__ Bind(&ok);
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index c334b91..8130965 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -1668,7 +1668,7 @@
}
-// Arg0: Onebyte String
+// Arg0: OneByteString (receiver)
// Arg1: Start index as Smi.
// Arg2: End index as Smi.
// The indexes must be valid.
@@ -1677,7 +1677,12 @@
const intptr_t kStartIndexOffset = 2 * kWordSize;
const intptr_t kEndIndexOffset = 1 * kWordSize;
Label fall_through, ok;
+ __ movl(EAX, Address(ESP, + kStartIndexOffset));
__ movl(EDI, Address(ESP, + kEndIndexOffset));
+ __ orl(EAX, EDI);
+ __ testl(EAX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, &fall_through); // 'start', 'end' not Smi.
+
__ subl(EDI, Address(ESP, + kStartIndexOffset));
TryAllocateOnebyteString(assembler, &ok, &fall_through, EDI);
__ Bind(&ok);
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index d150f52..de170c9 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -1659,7 +1659,7 @@
}
-// Arg0: Onebyte String
+// Arg0: OneByteString (receiver).
// Arg1: Start index as Smi.
// Arg2: End index as Smi.
// The indexes must be valid.
@@ -1671,6 +1671,10 @@
__ lw(T2, Address(SP, kEndIndexOffset));
__ lw(TMP, Address(SP, kStartIndexOffset));
+ __ or_(CMPRES, T2, TMP);
+ __ andi(CMPRES, CMPRES, Immediate(kSmiTagMask));
+ __ bne(CMPRES, ZR, &fall_through); // 'start', 'end' not Smi.
+
__ subu(T2, T2, TMP);
TryAllocateOnebyteString(assembler, &ok, &fall_through);
__ Bind(&ok);
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 62b2f5c..cd3c79f 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -1579,7 +1579,7 @@
}
-// Arg0: Onebyte String
+// Arg0: OneByteString (receiver).
// Arg1: Start index as Smi.
// Arg2: End index as Smi.
// The indexes must be valid.
@@ -1588,7 +1588,12 @@
const intptr_t kStartIndexOffset = 2 * kWordSize;
const intptr_t kEndIndexOffset = 1 * kWordSize;
Label fall_through, ok;
+ __ movq(RSI, Address(RSP, + kEndIndexOffset));
__ movq(RDI, Address(RSP, + kEndIndexOffset));
+ __ orq(RSI, RDI);
+ __ testq(RSI, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, &fall_through); // 'start', 'end' not Smi.
+
__ subq(RDI, Address(RSP, + kStartIndexOffset));
TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
__ Bind(&ok);
diff --git a/runtime/vm/mirrors_api_impl.cc b/runtime/vm/mirrors_api_impl.cc
index 1ab2323..ce15960 100644
--- a/runtime/vm/mirrors_api_impl.cc
+++ b/runtime/vm/mirrors_api_impl.cc
@@ -93,6 +93,7 @@
if (func.kind() == RawFunction::kImplicitGetter ||
func.kind() == RawFunction::kImplicitSetter ||
func.kind() == RawFunction::kImplicitStaticFinalGetter ||
+ func.kind() == RawFunction::kStaticInitializer ||
func.kind() == RawFunction::kMethodExtractor ||
func.kind() == RawFunction::kNoSuchMethodDispatcher) {
continue;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b638aef..0d4c8530 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1739,6 +1739,31 @@
}
+RawArray* Class::OffsetToFieldMap() const {
+ Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_);
+ if (array.IsNull()) {
+ ASSERT(is_finalized());
+ const intptr_t length = raw_ptr()->instance_size_in_words_;
+ array = Array::New(length, Heap::kOld);
+ Class& cls = Class::Handle(this->raw());
+ Array& fields = Array::Handle();
+ Field& f = Field::Handle();
+ while (!cls.IsNull()) {
+ fields = cls.fields();
+ for (intptr_t i = 0; i < fields.Length(); ++i) {
+ f ^= fields.At(i);
+ if (!f.is_static()) {
+ array.SetAt(f.Offset() >> kWordSizeLog2, f);
+ }
+ }
+ cls = cls.SuperClass();
+ }
+ StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw());
+ }
+ return array.raw();
+}
+
+
bool Class::HasInstanceFields() const {
const Array& field_array = Array::Handle(fields());
Field& field = Field::Handle();
@@ -4224,7 +4249,9 @@
RawFunction* Function::implicit_closure_function() const {
- if (IsClosureFunction() || IsSignatureFunction()) {
+ if (IsClosureFunction() ||
+ IsSignatureFunction() ||
+ IsStaticInitializerFunction()) {
return Function::null();
}
const Object& obj = Object::Handle(raw_ptr()->data_);
@@ -5427,6 +5454,35 @@
}
+RawFunction* Function::NewStaticInitializer(const String& field_name,
+ const AbstractType& result_type,
+ const Class& cls,
+ intptr_t initializer_pos) {
+ const String& init_name =
+ String::Handle(Symbols::New(String::Handle(
+ String::Concat(Symbols::InitPrefix(), field_name))));
+ const Function& init_function = Function::ZoneHandle(
+ Function::New(init_name,
+ RawFunction::kStaticInitializer,
+ true, // static
+ false, // !const
+ false, // !abstract
+ false, // !external
+ cls,
+ initializer_pos));
+ init_function.set_result_type(result_type);
+ // Static initializer functions are generated by the VM and are therfore
+ // hidden from the user. Since they are only executed once, we avoid
+ // optimizing and inlining them. After the field is initialized, the
+ // optimizing compiler can eliminate the call to the static initializer
+ // via constant folding.
+ init_function.set_is_visible(false);
+ init_function.set_is_optimizable(false);
+ init_function.set_is_inlinable(false);
+ return init_function.raw();
+}
+
+
const char* Function::ToCString() const {
const char* static_str = is_static() ? " static" : "";
const char* abstract_str = is_abstract() ? " abstract" : "";
@@ -5451,6 +5507,9 @@
case RawFunction::kImplicitSetter:
kind_str = " setter";
break;
+ case RawFunction::kStaticInitializer:
+ kind_str = " static-initializer";
+ break;
case RawFunction::kImplicitStaticFinalGetter:
kind_str = " static-final-getter";
break;
@@ -5522,6 +5581,9 @@
case RawFunction::kConstructor:
kind_string = "constructor";
break;
+ case RawFunction::kStaticInitializer:
+ kind_string = "static initializer";
+ break;
case RawFunction::kImplicitStaticFinalGetter:
kind_string = "static final getter";
break;
@@ -5960,17 +6022,58 @@
}
-void Field::UpdateCid(intptr_t cid) const {
+static intptr_t GetListLength(const Object& value) {
+ const intptr_t cid = value.GetClassId();
+ ASSERT(RawObject::IsBuiltinListClassId(cid));
+ // Extract list length.
+ if (value.IsTypedData()) {
+ const TypedData& list = TypedData::Cast(value);
+ return list.Length();
+ } else if (value.IsArray()) {
+ const Array& list = Array::Cast(value);
+ return list.Length();
+ } else if (value.IsGrowableObjectArray()) {
+ // List length is variable.
+ return Field::kNoFixedLength;
+ } else if (value.IsExternalTypedData()) {
+ // TODO(johnmccutchan): Enable for external typed data.
+ return Field::kNoFixedLength;
+ } else if (RawObject::IsTypedDataViewClassId(cid)) {
+ // TODO(johnmccutchan): Enable for typed data views.
+ return Field::kNoFixedLength;
+ }
+ UNIMPLEMENTED();
+ return Field::kNoFixedLength;
+}
+
+
+bool Field::UpdateGuardedCidAndLength(const Object& value) const {
+ const intptr_t cid = value.GetClassId();
+ bool deoptimize = UpdateCid(cid);
+ intptr_t list_length = Field::kNoFixedLength;
+ if ((guarded_cid() != kDynamicCid) &&
+ is_final() && RawObject::IsBuiltinListClassId(cid)) {
+ list_length = GetListLength(value);
+ }
+ deoptimize = UpdateLength(list_length) || deoptimize;
+ if (deoptimize) {
+ DeoptimizeDependentCode();
+ }
+ return deoptimize;
+}
+
+
+bool Field::UpdateCid(intptr_t cid) const {
if (guarded_cid() == kIllegalCid) {
// Field is assigned first time.
set_guarded_cid(cid);
set_is_nullable(cid == kNullCid);
- return;
+ return false;
}
if ((cid == guarded_cid()) || ((cid == kNullCid) && is_nullable())) {
// Class id of the assigned value matches expected class id and nullability.
- return;
+ return false;
}
if ((cid == kNullCid) && !is_nullable()) {
@@ -5989,11 +6092,11 @@
}
// Expected class id or nullability of the field changed.
- DeoptimizeDependentCode();
+ return true;
}
-void Field::UpdateLength(intptr_t list_length) const {
+bool Field::UpdateLength(intptr_t list_length) const {
ASSERT(is_final() || (!is_final() &&
(list_length < Field::kUnknownFixedLength)));
ASSERT((list_length == Field::kNoFixedLength) ||
@@ -6010,16 +6113,16 @@
if (list_length_unknown && list_length_changed && !force_invalidate) {
// List length set for first time.
set_guarded_list_length(list_length);
- return;
+ return false;
}
if (!list_length_changed && !force_invalidate) {
// List length unchanged.
- return;
+ return false;
}
// Multiple list lengths assigned here, stop tracking length.
set_guarded_list_length(Field::kNoFixedLength);
- DeoptimizeDependentCode();
+ return true;
}
@@ -8345,6 +8448,7 @@
all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
RECOGNIZED_LIST(CHECK_FINGERPRINTS);
INLINE_WHITE_LIST(CHECK_FINGERPRINTS);
+ POLYMORPHIC_TARGET_LIST(CHECK_FINGERPRINTS);
all_libs.Clear();
all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 81de3ce..75ba0b8 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -863,6 +863,10 @@
RawArray* fields() const { return raw_ptr()->fields_; }
void SetFields(const Array& value) const;
+ // Returns an array of all fields of this class and its superclasses indexed
+ // by offset in words.
+ RawArray* OffsetToFieldMap() const;
+
// Returns true if non-static fields are defined.
bool HasInstanceFields() const;
@@ -1589,6 +1593,7 @@
case RawFunction::kClosureFunction:
case RawFunction::kConstructor:
case RawFunction::kImplicitStaticFinalGetter:
+ case RawFunction::kStaticInitializer:
return false;
default:
UNREACHABLE();
@@ -1606,6 +1611,7 @@
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitSetter:
case RawFunction::kImplicitStaticFinalGetter:
+ case RawFunction::kStaticInitializer:
return true;
case RawFunction::kClosureFunction:
case RawFunction::kConstructor:
@@ -1809,6 +1815,11 @@
return kind() == RawFunction::kImplicitSetter;
}
+ // Returns true if this function represents an static initializer function.
+ bool IsStaticInitializerFunction() const {
+ return kind() == RawFunction::kStaticInitializer;
+ }
+
// Returns true if this function represents a (possibly implicit) closure
// function.
bool IsClosureFunction() const {
@@ -1867,6 +1878,13 @@
const Function& parent,
intptr_t token_pos);
+ // Creates a new static initializer function which is invoked in the implicit
+ // static getter function.
+ static RawFunction* NewStaticInitializer(const String& field_name,
+ const AbstractType& result_type,
+ const Class& cls,
+ intptr_t token_pos);
+
// Allocate new function object, clone values from this function. The
// owner of the clone is new_owner.
RawFunction* Clone(const Class& new_owner) const;
@@ -2124,13 +2142,9 @@
return OFFSET_OF(RawField, is_nullable_);
}
- // Update guarded class id and nullability of the field to reflect assignment
- // of the value with the given class id to this field. May trigger
- // deoptimization of dependent code.
- void UpdateCid(intptr_t cid) const;
- // Update guarded class length of the field to reflect assignment of the
- // value with the given length. May trigger deoptimization of dependent code.
- void UpdateLength(intptr_t length) const;
+ // Update guarded cid and guarded length for this field. May trigger
+ // deoptimization of dependent optimized code.
+ bool UpdateGuardedCidAndLength(const Object& value) const;
// Return the list of optimized code objects that were optimized under
// assumptions about guarded class id and nullability of this field.
@@ -2169,6 +2183,16 @@
class FinalBit : public BitField<bool, kFinalBit, 1> {};
class HasInitializerBit : public BitField<bool, kHasInitializerBit, 1> {};
+ // Update guarded class id and nullability of the field to reflect assignment
+ // of the value with the given class id to this field. Returns true, if
+ // deoptimization of dependent code is required.
+ bool UpdateCid(intptr_t cid) const;
+
+ // Update guarded class length of the field to reflect assignment of the
+ // value with the given length. Returns true if deoptimization of dependent
+ // code is required.
+ bool UpdateLength(intptr_t length) const;
+
void set_name(const String& value) const;
void set_is_static(bool is_static) const {
set_kind_bits(StaticBit::update(is_static, raw_ptr()->kind_bits_));
@@ -3828,6 +3852,7 @@
}
void SetField(const Field& field, const Object& value) const {
+ field.UpdateGuardedCidAndLength(value);
StorePointer(FieldAddr(field), value.raw());
}
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 5f27790..6ff23a5 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -781,6 +781,9 @@
case RawFunction::kImplicitStaticFinalGetter:
node_sequence = parser.ParseStaticFinalGetter(func);
break;
+ case RawFunction::kStaticInitializer:
+ node_sequence = parser.ParseStaticInitializer(func);
+ break;
case RawFunction::kMethodExtractor:
node_sequence = parser.ParseMethodExtractor(func);
break;
@@ -878,7 +881,44 @@
(LookaheadToken(5) == Token::kLPAREN))) {
expr = ParseNewOperator(Token::kCONST);
} else {
- expr = ParsePrimary();
+ // Can be x, C.x, or L.C.x.
+ expr = ParsePrimary(); // Consumes x, C or L.C.
+ Class& cls = Class::Handle();
+ if (expr->IsPrimaryNode()) {
+ PrimaryNode* primary_node = expr->AsPrimaryNode();
+ if (primary_node->primary().IsClass()) {
+ // If the primary node referred to a class we are loading a
+ // qualified static field.
+ cls ^= primary_node->primary().raw();
+ } else {
+ ErrorMsg(expr_pos, "Metadata expressions must refer to a const field "
+ "or constructor");
+ }
+ }
+ if (CurrentToken() == Token::kPERIOD) {
+ // C.x or L.C.X.
+ if (cls.IsNull()) {
+ ErrorMsg(expr_pos, "Metadata expressions must refer to a const field "
+ "or constructor");
+ }
+ ConsumeToken();
+ const intptr_t ident_pos = TokenPos();
+ String* ident = ExpectIdentifier("identifier expected");
+ const Field& field = Field::Handle(cls.LookupStaticField(*ident));
+ if (field.IsNull()) {
+ ErrorMsg(ident_pos,
+ "Class '%s' has no field '%s'",
+ cls.ToCString(),
+ ident->ToCString());
+ }
+ if (!field.is_const()) {
+ ErrorMsg(ident_pos,
+ "Field '%s' of class '%s' is not const",
+ ident->ToCString(),
+ cls.ToCString());
+ }
+ expr = GenerateStaticFieldLookup(field, TokenPos());
+ }
}
if (expr->EvalConstExpr() == NULL) {
ErrorMsg(expr_pos, "expression must be a compile-time constant");
@@ -907,33 +947,17 @@
const Field& field =
Field::ZoneHandle(field_class.LookupStaticField(field_name));
- if (!field.is_const() &&
- (field.value() != Object::transition_sentinel().raw()) &&
- (field.value() != Object::sentinel().raw())) {
- // The field has already been initialized at compile time (this can
- // happen, e.g., if we are recompiling for optimization). There is no
- // need to check for initialization and compile the potentially very
- // large initialization code. By skipping this code, the deoptimization
- // ids will not line up with the original code, but this is safe because
- // LoadStaticField does not deoptimize.
- LoadStaticFieldNode* load_node = new LoadStaticFieldNode(ident_pos, field);
- ReturnNode* return_node = new ReturnNode(ident_pos, load_node);
- current_block_->statements->Add(return_node);
- return CloseBlock();
- }
-
- // Static const fields must have an initializer.
+ // Static final fields must have an initializer.
ExpectToken(Token::kASSIGN);
- // We don't want to use ParseConstExpr() here because we don't want
- // the constant folding code to create, compile and execute a code
- // fragment to evaluate the expression. Instead, we just make sure
- // the static const field initializer is a constant expression and
- // leave the evaluation to the getter function.
const intptr_t expr_pos = TokenPos();
- AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
-
if (field.is_const()) {
+ // We don't want to use ParseConstExpr() here because we don't want
+ // the constant folding code to create, compile and execute a code
+ // fragment to evaluate the expression. Instead, we just make sure
+ // the static const field initializer is a constant expression and
+ // leave the evaluation to the getter function.
+ AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
// This getter will only be called once at compile time.
if (expr->EvalConstExpr() == NULL) {
ErrorMsg(expr_pos, "initializer is not a valid compile-time constant");
@@ -995,7 +1019,19 @@
// we leave the field value as 'transition_sentinel', which is wrong.
// A second reference to the field later throws a circular dependency
// exception. The field should instead be set to null after an exception.
- initialize_field->Add(new StoreStaticFieldNode(ident_pos, field, expr));
+ const String& init_name =
+ String::Handle(Symbols::New(String::Handle(
+ String::Concat(Symbols::InitPrefix(), String::Handle(field.name())))));
+ const Function& init_function = Function::ZoneHandle(
+ field_class.LookupStaticFunction(init_name));
+ ASSERT(!init_function.IsNull());
+ ArgumentListNode* arguments = new ArgumentListNode(expr_pos);
+ StaticCallNode* init_call =
+ new StaticCallNode(expr_pos, init_function, arguments);
+
+ initialize_field->Add(new StoreStaticFieldNode(ident_pos,
+ field,
+ init_call));
AstNode* uninitialized_check =
new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL);
current_block_->statements->Add(uninitialized_check);
@@ -1010,6 +1046,25 @@
}
+SequenceNode* Parser::ParseStaticInitializer(const Function& func) {
+ TRACE_PARSER("ParseStaticInitializer");
+ ParamList params;
+ ASSERT(func.num_fixed_parameters() == 0); // static.
+ ASSERT(!func.HasOptionalParameters());
+ ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
+
+ // Build local scope for function and populate with the formal parameters.
+ OpenFunctionBlock(func);
+ AddFormalParamsToScope(¶ms, current_block_->scope);
+
+ intptr_t expr_pos = func.token_pos();
+ AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
+ ReturnNode* return_node = new ReturnNode(expr_pos, expr);
+ current_block_->statements->Add(return_node);
+ return CloseBlock();
+}
+
+
// Create AstNodes for an implicit instance getter method:
// LoadLocalNode 0 ('this');
// LoadInstanceFieldNode (field_name);
@@ -2091,8 +2146,7 @@
if (found) continue;
- field.UpdateCid(kNullCid);
- field.UpdateLength(Field::kNoFixedLength);
+ field.UpdateGuardedCidAndLength(Object::Handle());
}
}
@@ -3253,6 +3307,7 @@
Function& setter = Function::Handle();
Field& class_field = Field::ZoneHandle();
Instance& init_value = Instance::Handle();
+ intptr_t expr_pos = -1;
while (true) {
bool has_initializer = CurrentToken() == Token::kASSIGN;
bool has_simple_literal = false;
@@ -3277,6 +3332,7 @@
(LookaheadToken(1) == Token::kSEMICOLON)) {
has_simple_literal = IsSimpleLiteral(*field->type, &init_value);
}
+ expr_pos = TokenPos();
SkipExpr();
} else {
// Static const and static final fields must have an initializer.
@@ -3320,6 +3376,14 @@
field->name_pos);
getter.set_result_type(*field->type);
members->AddFunction(getter);
+
+ // Create initializer function.
+ const Function& init_function = Function::ZoneHandle(
+ Function::NewStaticInitializer(*field->name,
+ *field->type,
+ current_class(),
+ expr_pos));
+ members->AddFunction(init_function);
}
}
@@ -4429,6 +4493,7 @@
if ((is_const || is_final) && (LookaheadToken(1) == Token::kSEMICOLON)) {
has_simple_literal = IsSimpleLiteral(type, &field_value);
}
+ const intptr_t expr_pos = TokenPos();
SkipExpr();
field.set_value(field_value);
if (!has_simple_literal) {
@@ -4444,6 +4509,14 @@
name_pos);
getter.set_result_type(type);
top_level->functions.Add(getter);
+
+ // Create initializer function.
+ const Function& init_function = Function::ZoneHandle(
+ Function::NewStaticInitializer(var_name,
+ type,
+ current_class(),
+ expr_pos));
+ top_level->functions.Add(init_function);
}
} else if (is_final) {
ErrorMsg(name_pos, "missing initializer for final or const variable");
@@ -6441,8 +6514,7 @@
Resolver::ResolveStatic(cls,
func_name,
arguments->length(),
- arguments->names(),
- Resolver::kIsQualified));
+ arguments->names()));
ASSERT(!func.IsNull());
return new StaticCallNode(arguments->token_pos(), func, arguments);
}
@@ -7963,8 +8035,7 @@
Resolver::ResolveStatic(cls,
func_name,
num_arguments,
- arguments->names(),
- Resolver::kIsQualified));
+ arguments->names()));
if (func.IsNull()) {
// Check if there is a static field of the same name, it could be a closure
// and so we try and invoke the closure.
@@ -7979,8 +8050,7 @@
func = Resolver::ResolveStatic(cls,
getter_name,
kNumArguments,
- Object::empty_array(),
- Resolver::kIsQualified);
+ Object::empty_array());
if (!func.IsNull()) {
ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter);
EnsureSavedCurrentContext();
@@ -8088,8 +8158,7 @@
func = Resolver::ResolveStatic(cls,
getter_name,
kNumArguments,
- Object::empty_array(),
- Resolver::kIsQualified);
+ Object::empty_array());
if (func.IsNull()) {
// We might be referring to an implicit closure, check to see if
// there is a function of the same name.
@@ -8659,8 +8728,7 @@
Function::Handle(Resolver::ResolveStatic(field_owner,
getter_name,
kNumArguments,
- Object::empty_array(),
- Resolver::kIsQualified));
+ Object::empty_array()));
ASSERT(!func.IsNull());
ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter);
Object& const_value = Object::Handle(
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 5ccaca5..41798e3 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -464,6 +464,7 @@
SequenceNode* ParseInstanceGetter(const Function& func);
SequenceNode* ParseInstanceSetter(const Function& func);
SequenceNode* ParseStaticFinalGetter(const Function& func);
+ SequenceNode* ParseStaticInitializer(const Function& func);
SequenceNode* ParseMethodExtractor(const Function& func);
SequenceNode* ParseNoSuchMethodDispatcher(const Function& func,
Array& default_values);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ee59096..0eb68b8 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -477,6 +477,7 @@
RawString* name_;
RawArray* functions_;
RawArray* fields_;
+ RawArray* offset_in_words_to_field_;
RawGrowableObjectArray* closure_functions_; // Local functions and literals.
RawArray* interfaces_; // Array of AbstractType.
RawGrowableObjectArray* direct_subclasses_; // Array of Class.
@@ -602,6 +603,7 @@
kImplicitSetter, // represents an implicit setter for fields.
kImplicitStaticFinalGetter, // represents an implicit getter for static
// final fields (incl. static const fields).
+ kStaticInitializer, // used in implicit static getters.
kMethodExtractor, // converts method into implicit closure on the receiver.
kNoSuchMethodDispatcher, // invokes noSuchMethod.
kInvokeFieldDispatcher, // invokes a field as a closure.
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index e714f44..27ad524 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -2654,7 +2654,14 @@
void RawMirrorReference::WriteTo(SnapshotWriter* writer,
intptr_t object_id,
Snapshot::Kind kind) {
- UNREACHABLE();
+ if (kind == Snapshot::kMessage) {
+ // We do not allow objects with native fields in an isolate message.
+ writer->SetWriteException(Exceptions::kArgument,
+ "Illegal argument in isolate message"
+ " : (object is a MirrorReference)");
+ } else {
+ UNREACHABLE();
+ }
}
} // namespace dart
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index 1b43064..211c15e 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -144,8 +144,7 @@
const String& class_name,
const String& function_name,
intptr_t num_arguments,
- const Array& argument_names,
- StaticResolveType resolve_type) {
+ const Array& argument_names) {
ASSERT(!library.IsNull());
Function& function = Function::Handle();
if (class_name.IsNull() || (class_name.Length() == 0)) {
@@ -181,8 +180,7 @@
function = ResolveStatic(cls,
function_name,
num_arguments,
- argument_names,
- resolve_type);
+ argument_names);
}
if (FLAG_trace_resolving && function.IsNull()) {
OS::Print("ResolveStatic error: function '%s.%s' not found.\n",
@@ -194,41 +192,16 @@
}
-RawFunction* Resolver::ResolveStaticByName(const Class& cls,
- const String& function_name,
- StaticResolveType resolve_type) {
- ASSERT(!cls.IsNull());
-
- if (FLAG_trace_resolving) {
- OS::Print("ResolveStatic '%s'\n", function_name.ToCString());
- }
-
- // Now look for a static function whose name matches function_name
- // in the class.
- Function& function =
- Function::Handle(cls.LookupStaticFunction(function_name));
- if (resolve_type == kNotQualified) {
- // Walk the hierarchy.
- Class& super_class = Class::Handle(cls.SuperClass());
- while (function.IsNull()) {
- function = super_class.LookupStaticFunction(function_name);
- super_class = super_class.SuperClass();
- if (super_class.IsNull()) break;
- }
- }
- return function.raw();
-}
-
-
-
RawFunction* Resolver::ResolveStatic(const Class& cls,
const String& function_name,
intptr_t num_arguments,
- const Array& argument_names,
- StaticResolveType resolve_type) {
+ const Array& argument_names) {
ASSERT(!cls.IsNull());
- const Function& function = Function::Handle(
- ResolveStaticByName(cls, function_name, resolve_type));
+ if (FLAG_trace_resolving) {
+ OS::Print("ResolveStatic '%s'\n", function_name.ToCString());
+ }
+ const Function& function =
+ Function::Handle(cls.LookupStaticFunction(function_name));
if (function.IsNull() ||
!function.AreValidArguments(num_arguments, argument_names, NULL)) {
// Return a null function to signal to the upper levels to throw a
diff --git a/runtime/vm/resolver.h b/runtime/vm/resolver.h
index a0f2b33..32ef3bc 100644
--- a/runtime/vm/resolver.h
+++ b/runtime/vm/resolver.h
@@ -37,11 +37,6 @@
const Class& receiver_class,
const String& function_name);
- enum StaticResolveType {
- kIsQualified,
- kNotQualified
- };
-
// Resolve specified dart static function. If library.IsNull, use
// either application library or core library if no application library
// exists. Passing negative num_arguments means that the function
@@ -52,20 +47,13 @@
const String& cls_name,
const String& function_name,
intptr_t num_arguments,
- const Array& argument_names,
- StaticResolveType resolve_type);
-
- // Resolve specified dart static function.
- static RawFunction* ResolveStaticByName(const Class& cls,
- const String& function_name,
- StaticResolveType resolve_type);
+ const Array& argument_names);
// Resolve specified dart static function with specified arity.
static RawFunction* ResolveStatic(const Class& cls,
const String& function_name,
intptr_t num_arguments,
- const Array& argument_names,
- StaticResolveType resolve_type);
+ const Array& argument_names);
};
} // namespace dart
diff --git a/runtime/vm/resolver_test.cc b/runtime/vm/resolver_test.cc
index 6ede57c..22c4dd5 100644
--- a/runtime/vm/resolver_test.cc
+++ b/runtime/vm/resolver_test.cc
@@ -79,7 +79,6 @@
const char* test_class_name = "A";
const char* test_static_function_name = "static_foo";
const int kTestValue = 42;
- const Resolver::StaticResolveType kResolveType = Resolver::kIsQualified;
// Setup a static function which can be invoked.
SetupStaticFunction(test_library_name,
@@ -101,8 +100,7 @@
class_name,
static_function_name,
kNumArguments,
- Object::empty_array(),
- kResolveType));
+ Object::empty_array()));
EXPECT(!function.IsNull()); // No ambiguity error expected.
const Array& args = Array::Handle(Array::New(kNumArguments));
const String& arg0 = String::Handle(String::New("junk"));
@@ -122,8 +120,7 @@
class_name,
static_function_name,
kNumArguments,
- Object::empty_array(),
- kResolveType));
+ Object::empty_array()));
EXPECT(bad_function.IsNull()); // No ambiguity error expected.
}
@@ -138,8 +135,7 @@
super_class_name,
super_static_function_name,
kNumArguments,
- Object::empty_array(),
- kResolveType));
+ Object::empty_array()));
EXPECT(!super_function.IsNull()); // No ambiguity error expected.
}
}
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 6df4672..5584104 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -150,6 +150,8 @@
isolate_(isolate),
cls_(Class::Handle()),
obj_(Object::Handle()),
+ array_(Array::Handle()),
+ field_(Field::Handle()),
str_(String::Handle()),
library_(Library::Handle()),
type_(AbstractType::Handle()),
@@ -789,9 +791,26 @@
instance_size = cls_.instance_size();
}
intptr_t offset = Object::InstanceSize();
+ intptr_t result_cid = result->GetClassId();
while (offset < instance_size) {
obj_ = ReadObjectRef();
result->SetFieldAtOffset(offset, obj_);
+ if (kind_ == Snapshot::kMessage) {
+ // TODO(fschneider): Consider hoisting these lookups out of the loop.
+ // This would involve creating a handle, since cls_ can't be reused
+ // across the call to ReadObjectRef.
+ cls_ = isolate()->class_table()->At(result_cid);
+ array_ = cls_.OffsetToFieldMap();
+ field_ ^= array_.At(offset >> kWordSizeLog2);
+ // Entries can be null because offset can be outside of instance fields
+ // due to rounded allocation size.
+ if (!field_.IsNull()) {
+ ASSERT(field_.Offset() == offset);
+ field_.UpdateGuardedCidAndLength(obj_);
+ }
+ }
+ // TODO(fschneider): Verify the guarded cid and length for other kinds of
+ // snapshot (kFull, kScript) with asserts.
offset += kWordSize;
}
if (kind_ == Snapshot::kFull) {
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 4643a51..ff65e52 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -320,6 +320,8 @@
Isolate* isolate_; // Current isolate.
Class& cls_; // Temporary Class handle.
Object& obj_; // Temporary Object handle.
+ Array& array_; // Temporary Array handle.
+ Field& field_; // Temporary Field handle.
String& str_; // Temporary String handle.
Library& library_; // Temporary library handle.
AbstractType& type_; // Temporary type handle.
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index d52e244..a9a3095 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -261,6 +261,7 @@
V(_as, "_as") \
V(GetterPrefix, "get:") \
V(SetterPrefix, "set:") \
+ V(InitPrefix, "init:") \
V(PrivateGetterPrefix, "get:_") \
V(PrivateSetterPrefix, "set:_") \
V(_New, "_new") \
diff --git a/sdk/lib/_internal/compiler/compiler.dart b/sdk/lib/_internal/compiler/compiler.dart
index b6e5394..e40c74a 100644
--- a/sdk/lib/_internal/compiler/compiler.dart
+++ b/sdk/lib/_internal/compiler/compiler.dart
@@ -85,8 +85,9 @@
Uri packageRoot,
CompilerInputProvider inputProvider,
DiagnosticHandler handler,
- [List<String> options = const [],
- CompilerOutputProvider outputProvider]) {
+ [List<String> options = const [],
+ CompilerOutputProvider outputProvider,
+ Map<String, dynamic> environment = const {}]) {
if (!libraryRoot.path.endsWith("/")) {
throw new ArgumentError("libraryRoot must end with a /");
}
@@ -100,7 +101,8 @@
handler,
libraryRoot,
packageRoot,
- options);
+ options,
+ environment);
// TODO(ahe): Use the value of the future (which signals success or failure).
return compiler.run(script).then((_) {
String code = compiler.assembledCode;
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index 022acb4..cc8be6e 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -20,6 +20,7 @@
final Uri libraryRoot;
final Uri packageRoot;
List<String> options;
+ Map<String, dynamic> environment;
bool mockableLibraryUsed = false;
final Set<String> allowedLibraryCategories;
@@ -28,7 +29,8 @@
this.handler,
this.libraryRoot,
this.packageRoot,
- List<String> options)
+ List<String> options,
+ this.environment)
: this.options = options,
this.allowedLibraryCategories = getAllowedLibraryCategories(options),
super(
@@ -329,4 +331,6 @@
print('$message: ${tryToString(exception)}');
print(tryToString(stackTrace));
}
+
+ fromEnvironment(String name) => environment[name];
}
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 7f666d3..5141109 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -149,7 +149,7 @@
// more general solution.
class BoxElement extends ElementX {
BoxElement(String name, Element enclosingElement)
- : super(name, ElementKind.VARIABLE, enclosingElement);
+ : super(name, ElementKind.VARIABLE_LIST, enclosingElement);
DartType computeType(Compiler compiler) => compiler.types.dynamicType;
}
@@ -389,7 +389,7 @@
// A boxed element.
freeVariableMapping[fromElement] = updatedElement;
Element boxElement = updatedElement.enclosingElement;
- assert(boxElement.kind == ElementKind.VARIABLE);
+ assert(boxElement is BoxElement);
boxes.add(boxElement);
}
});
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index 735d2f1..e7d3b79 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -634,7 +634,77 @@
return evaluateArgumentsToConstructor(
node, selector, send.arguments, constructor);
}
- return makeConstructedConstant(node, type, constructor, evaluateArguments);
+
+ if (constructor == compiler.intEnvironment
+ || constructor == compiler.boolEnvironment
+ || constructor == compiler.stringEnvironment) {
+ List<Constant> arguments = evaluateArguments(constructor.implementation);
+ var firstArgument = arguments[0];
+ Constant defaultValue = arguments[1];
+
+ if (firstArgument is NullConstant) {
+ compiler.reportFatalError(
+ send.arguments.head, MessageKind.NULL_NOT_ALLOWED);
+ }
+
+ if (firstArgument is! StringConstant) {
+ DartType type = defaultValue.computeType(compiler);
+ compiler.reportFatalError(
+ send.arguments.head, MessageKind.NOT_ASSIGNABLE.error,
+ {'fromType': type, 'toType': compiler.stringClass.rawType});
+ }
+
+ if (constructor == compiler.intEnvironment
+ && !(defaultValue is NullConstant || defaultValue is IntConstant)) {
+ DartType type = defaultValue.computeType(compiler);
+ compiler.reportFatalError(
+ send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE.error,
+ {'fromType': type, 'toType': compiler.intClass.rawType});
+ }
+
+ if (constructor == compiler.boolEnvironment
+ && !(defaultValue is NullConstant || defaultValue is BoolConstant)) {
+ DartType type = defaultValue.computeType(compiler);
+ compiler.reportFatalError(
+ send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE.error,
+ {'fromType': type, 'toType': compiler.boolClass.rawType});
+ }
+
+ if (constructor == compiler.stringEnvironment
+ && !(defaultValue is NullConstant
+ || defaultValue is StringConstant)) {
+ DartType type = defaultValue.computeType(compiler);
+ compiler.reportFatalError(
+ send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE.error,
+ {'fromType': type, 'toType': compiler.stringClass.rawType});
+ }
+
+ String value =
+ compiler.fromEnvironment(firstArgument.value.slowToString());
+
+ if (value == null) {
+ return defaultValue;
+ } else if (constructor == compiler.intEnvironment) {
+ int number = int.parse(value, onError: (_) => null);
+ return (number == null)
+ ? defaultValue
+ : constantSystem.createInt(number);
+ } else if (constructor == compiler.boolEnvironment) {
+ if (value == 'true') {
+ return constantSystem.createBool(true);
+ } else if (value == 'false') {
+ return constantSystem.createBool(false);
+ } else {
+ return defaultValue;
+ }
+ } else {
+ assert(constructor == compiler.stringEnvironment);
+ return constantSystem.createString(new DartString.literal(value), node);
+ }
+ } else {
+ return makeConstructedConstant(
+ node, type, constructor, evaluateArguments);
+ }
}
Constant makeConstructedConstant(
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index d0d79d3..067ee88 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -473,6 +473,11 @@
Element identicalFunction;
Element functionApplyMethod;
Element invokeOnMethod;
+ Element intEnvironment;
+ Element boolEnvironment;
+ Element stringEnvironment;
+
+ fromEnvironment(String name) => null;
Element get currentElement => _currentElement;
@@ -571,6 +576,8 @@
Compiler.NO_SUCH_METHOD, null, Compiler.NO_SUCH_METHOD_ARG_COUNT);
final Selector symbolValidatedConstructorSelector = new Selector.call(
'validated', null, 1);
+ final Selector fromEnvironmentSelector = new Selector.callConstructor(
+ 'fromEnvironment', null, 2);
bool enabledNoSuchMethod = false;
bool enabledRuntimeType = false;
@@ -852,6 +859,13 @@
symbolValidatedConstructorSelector);
} else if (mirrorsUsedClass == cls) {
mirrorsUsedConstructor = cls.constructors.head;
+ } else if (intClass == cls) {
+ intEnvironment = intClass.lookupConstructor(fromEnvironmentSelector);
+ } else if (stringClass == cls) {
+ stringEnvironment =
+ stringClass.lookupConstructor(fromEnvironmentSelector);
+ } else if (boolClass == cls) {
+ boolEnvironment = boolClass.lookupConstructor(fromEnvironmentSelector);
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index 2990a9e..7869913 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -112,6 +112,7 @@
// TODO(johnniwinther): Measure time for reading files.
SourceFileProvider inputProvider = new CompilerSourceFileProvider();
diagnosticHandler = new FormattingDiagnosticHandler(inputProvider);
+ Map<String, dynamic> environment = new Map<String, dynamic>();
passThrough(String argument) => options.add(argument);
@@ -174,6 +175,13 @@
passThrough('--verbose');
}
+ addInEnvironment(String argument) {
+ int eqIndex = argument.indexOf('=');
+ String name = argument.substring(2, eqIndex);
+ String value = argument.substring(eqIndex + 1);
+ environment[name] = value;
+ }
+
setCategories(String argument) {
List<String> categories = extractParameter(argument).split(',');
Set<String> allowedCategories =
@@ -275,6 +283,7 @@
new OptionHandler('--terse', passThrough),
new OptionHandler('--disallow-unsafe-eval',
(_) => hasDisallowUnsafeEval = true),
+ new OptionHandler('-D.+=.*', addInEnvironment),
// The following two options must come last.
new OptionHandler('-.*', (String argument) {
@@ -411,7 +420,7 @@
return api.compile(uri, libraryRoot, packageRoot,
inputProvider, diagnosticHandler,
- options, outputProvider)
+ options, outputProvider, environment)
.then(compilationDone);
}
@@ -494,6 +503,9 @@
-v, --verbose
Display verbose information.
+ -D<name>=<value>
+ Define an environment variable.
+
--version
Display version information.
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 36ce3e4..8af9dfc 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -552,6 +552,16 @@
&& node.arguments.tail.tail.isEmpty;
}
+ static bool isConstructorOfTypedArraySubclass(Element element,
+ Compiler compiler) {
+ if (compiler.typedDataClass == null) return false;
+ ClassElement cls = element.getEnclosingClass();
+ if (cls == null || !element.isConstructor()) return false;
+ return compiler.world.isSubclass(compiler.typedDataClass, cls)
+ && cls.getLibrary() == compiler.typedDataLibrary
+ && element.name == '';
+ }
+
static bool switchStatementHasContinue(SwitchStatement node,
TreeElements elements) {
for (SwitchCase switchCase in node.cases) {
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
index 9be28ab..d433dd5 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
@@ -149,6 +149,11 @@
T typeOfElement(Element element);
/**
+ * Returns the return type of [element].
+ */
+ T returnTypeOfElement(Element element);
+
+ /**
* Records that [node] sets final field [element] to be of type [type].
*
* [nodeHolder] is the element holder of [node].
@@ -845,6 +850,18 @@
node, () => types.allocateContainer(
types.fixedListType, node, outermostElement,
elementType, initialLength));
+ } else if (Elements.isConstructorOfTypedArraySubclass(element, compiler)) {
+ int initialLength;
+ LiteralInt length = node.arguments.head.asLiteralInt();
+ if (length != null) {
+ initialLength = length.value;
+ }
+ T elementType = inferrer.returnTypeOfElement(
+ element.getEnclosingClass().lookupMember('[]'));
+ return inferrer.concreteTypes.putIfAbsent(
+ node, () => types.allocateContainer(
+ types.nonNullExact(element.getEnclosingClass()), node,
+ outermostElement, elementType, initialLength));
} else if (element.isFunction() || element.isConstructor()) {
return returnType;
} else {
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
index 13ccddc..6b39f4c 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -253,16 +253,23 @@
Node node,
Element enclosing,
[TypeInformation elementType, int length]) {
+ bool isTypedArray = (compiler.typedDataClass != null)
+ && type.type.satisfies(compiler.typedDataClass, compiler);
bool isConst = (type.type == compiler.typesTask.constListType);
- bool isFixed = (type.type == compiler.typesTask.fixedListType) || isConst;
+ bool isFixed = (type.type == compiler.typesTask.fixedListType)
+ || isConst
+ || isTypedArray;
+ bool isElementInferred = isConst || isTypedArray;
int inferredLength = isFixed ? length : null;
- TypeMask elementTypeMask = isConst ? elementType.type : dynamicType.type;
+ TypeMask elementTypeMask = isElementInferred
+ ? elementType.type
+ : dynamicType.type;
ContainerTypeMask mask = new ContainerTypeMask(
type.type, node, enclosing, elementTypeMask, inferredLength);
ElementInContainerTypeInformation element =
new ElementInContainerTypeInformation(elementType);
- element.inferred = isConst;
+ element.inferred = isElementInferred;
allocatedTypes.add(element);
return allocatedContainers[node] =
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
index 3afb829..b6a2cab 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
@@ -197,7 +197,7 @@
* return type.
*
* Note that a few elements of these kinds must be treated specially,
- * and they are dealt in [ElementTypeInformation.handleSpecialCase]:
+ * and they are dealt in [ElementTypeInformation.handleSpecialCases]:
*
* - Parameters of closures, [noSuchMethod] and [call] instance
* methods: we currently do not infer types for those.
@@ -298,6 +298,18 @@
}
}
}
+
+ Compiler compiler = inferrer.compiler;
+ if (element.declaration == compiler.intEnvironment) {
+ giveUp(inferrer);
+ return compiler.typesTask.intType.nullable();
+ } else if (element.declaration == compiler.boolEnvironment) {
+ giveUp(inferrer);
+ return compiler.typesTask.boolType.nullable();
+ } else if (element.declaration == compiler.stringEnvironment) {
+ giveUp(inferrer);
+ return compiler.typesTask.stringType.nullable();
+ }
return null;
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 4a94609..cdceeec 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -5,10 +5,8 @@
part of js_backend;
class JavaScriptItemCompilationContext extends ItemCompilationContext {
- final Set<HInstruction> boundsChecked;
-
- JavaScriptItemCompilationContext()
- : boundsChecked = new Set<HInstruction>();
+ final Set<HInstruction> boundsChecked = new Set<HInstruction>();
+ final Set<HInstruction> allocatedFixedLists = new Set<HInstruction>();
}
class CheckedModeHelper {
@@ -207,20 +205,21 @@
*/
Element mapTypeToInterceptor;
- HType stringType;
- HType doubleType;
- HType intType;
- HType numType;
- HType boolType;
- HType indexablePrimitiveType;
- HType readableArrayType;
- HType mutableArrayType;
- HType fixedArrayType;
- HType extendableArrayType;
- HType nonNullType;
- HType dynamicType;
- HType nullType = const HBoundedType(const TypeMask.empty());
- HType emptyType = const HBoundedType(const TypeMask.nonNullEmpty());
+ TypeMask get stringType => compiler.typesTask.stringType;
+ TypeMask get doubleType => compiler.typesTask.doubleType;
+ TypeMask get intType => compiler.typesTask.intType;
+ TypeMask get numType => compiler.typesTask.numType;
+ TypeMask get boolType => compiler.typesTask.boolType;
+ TypeMask get dynamicType => compiler.typesTask.dynamicType;
+ TypeMask get nullType => compiler.typesTask.nullType;
+ TypeMask get emptyType => const TypeMask.nonNullEmpty();
+ TypeMask indexablePrimitiveType;
+ TypeMask readableArrayType;
+ TypeMask mutableArrayType;
+ TypeMask fixedArrayType;
+ TypeMask extendableArrayType;
+ TypeMask nonNullType;
+
Element getNativeInterceptorMethod;
bool needToInitializeDispatchProperty = false;
@@ -613,32 +612,14 @@
validateInterceptorImplementsAllObjectMethods(jsInterceptorClass);
- stringType = new HBoundedType(
- new TypeMask.nonNullExact(jsStringClass));
- doubleType = new HBoundedType(
- new TypeMask.nonNullExact(jsDoubleClass));
- intType = new HBoundedType(
- new TypeMask.nonNullExact(jsIntClass));
- numType = new HBoundedType(
- new TypeMask.nonNullSubclass(jsNumberClass));
- boolType = new HBoundedType(
- new TypeMask.nonNullExact(jsBoolClass));
- indexablePrimitiveType = new HBoundedType(
- new TypeMask.nonNullSubtype(jsIndexableClass));
- readableArrayType = new HBoundedType(
- new TypeMask.nonNullSubclass(jsArrayClass));
- mutableArrayType = new HBoundedType(
- new TypeMask.nonNullSubclass(jsMutableArrayClass));
- fixedArrayType = new HBoundedType(
- new TypeMask.nonNullExact(jsFixedArrayClass));
- extendableArrayType = new HBoundedType(
- new TypeMask.nonNullExact(jsExtendableArrayClass));
- nonNullType = new HBoundedType(
- compiler.typesTask.dynamicType.nonNullable());
- dynamicType = new HBoundedType(
- compiler.typesTask.dynamicType);
-
typeVariableClass = compiler.findHelper('TypeVariable');
+
+ indexablePrimitiveType = new TypeMask.nonNullSubtype(jsIndexableClass);
+ readableArrayType = new TypeMask.nonNullSubclass(jsArrayClass);
+ mutableArrayType = new TypeMask.nonNullSubclass(jsMutableArrayClass);
+ fixedArrayType = new TypeMask.nonNullExact(jsFixedArrayClass);
+ extendableArrayType = new TypeMask.nonNullExact(jsExtendableArrayClass);
+ nonNullType = compiler.typesTask.dynamicType.nonNullable();
}
void validateInterceptorImplementsAllObjectMethods(
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
index 6ea330e..888447e 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
@@ -355,11 +355,15 @@
if (!backend.isNeededForReflection(classElement)) {
buffer.write(',$n$n"+$reflectionName": 0');
} else {
- List<int> interfaces = <int>[];
- for (DartType interface in classElement.interfaces) {
- interfaces.add(task.metadataEmitter.reifyType(interface));
+ List<int> types = <int>[];
+ if (classElement.supertype != null) {
+ types.add(
+ task.metadataEmitter.reifyType(classElement.supertype));
}
- buffer.write(',$n$n"+$reflectionName": $interfaces');
+ for (DartType interface in classElement.interfaces) {
+ types.add(task.metadataEmitter.reifyType(interface));
+ }
+ buffer.write(',$n$n"+$reflectionName": $types');
}
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
index d90caf6..373b65d 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
@@ -23,7 +23,7 @@
if (!init.mangledNames) init.mangledNames = map();
if (!init.mangledGlobalNames) init.mangledGlobalNames = map();
if (!init.statics) init.statics = map();
- if (!init.interfaces) init.interfaces = map();
+ if (!init.typeInformation) init.typeInformation = map();
if (!init.globalFunctions) init.globalFunctions = map();
var libraries = init.libraries;
var mangledNames = init.mangledNames;
@@ -65,7 +65,7 @@
if (descriptor[property] == 1) ''' // Break long line.
'''descriptor[previousProperty].$reflectableField = 1;
if (element && element.length) ''' // Break long line.
-'''init.interfaces[previousProperty] = element;
+'''init.typeInformation[previousProperty] = element;
} else if (firstChar === "@") {
property = property.substring(1);
${namer.CURRENT_ISOLATE}[property][$metadataField] = element;
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 94ace737..987b996 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -223,7 +223,9 @@
Compiler compiler = new apiimpl.Compiler(inputProvider,
null,
internalDiagnosticHandler,
- libraryRoot, packageRoot, options);
+ libraryRoot, packageRoot,
+ options,
+ const {});
compiler.librariesToAnalyzeWhenRun = libraries;
return compiler.run(null).then((bool success) {
if (success && !compilationFailed) {
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 20259e7..40703cf 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -4073,30 +4073,38 @@
* first.
*/
void calculateAllSupertypes(ClassElement cls) {
- // TODO(karlklose): Check if type arguments match, if a class
- // element occurs more than once in the supertypes.
if (cls.allSupertypes != null) return;
final DartType supertype = cls.supertype;
if (supertype != null) {
+ Map<Element, DartType> instantiations = new Map<Element, DartType>();
LinkBuilder<DartType> allSupertypes = new LinkBuilder<DartType>();
- void add(DartType type) {
+ void addSupertype(DartType type) {
+ DartType existing =
+ instantiations.putIfAbsent(type.element, () => type);
+ if (existing != null && existing != type) {
+ compiler.reportError(cls,
+ MessageKind.MULTI_INHERITANCE,
+ {'thisType': cls.computeType(compiler),
+ 'firstType': existing,
+ 'secondType': type});
+ }
if (type.element != compiler.objectClass) {
allSupertypes.addLast(type);
}
}
- add(supertype);
+ addSupertype(supertype);
for (Link<DartType> interfaces = cls.interfaces;
!interfaces.isEmpty;
interfaces = interfaces.tail) {
- add(interfaces.head);
+ addSupertype(interfaces.head);
}
- addAllSupertypes(allSupertypes, supertype);
+ addAllSupertypes(addSupertype, supertype);
for (Link<DartType> interfaces = cls.interfaces;
!interfaces.isEmpty;
interfaces = interfaces.tail) {
- addAllSupertypes(allSupertypes, interfaces.head);
+ addAllSupertypes(addSupertype, interfaces.head);
}
allSupertypes.addLast(compiler.objectClass.rawType);
@@ -4111,7 +4119,7 @@
* Adds [type] and all supertypes of [type] to [allSupertypes] while
* substituting type variables.
*/
- void addAllSupertypes(LinkBuilder<DartType> allSupertypes,
+ void addAllSupertypes(void addSupertype(DartType supertype),
InterfaceType type) {
Link<DartType> typeArguments = type.typeArguments;
ClassElement classElement = type.element;
@@ -4124,7 +4132,7 @@
DartType supertype = supertypes.head;
if (supertype.element != compiler.objectClass) {
DartType substituted = supertype.subst(typeArguments, typeVariables);
- allSupertypes.addLast(substituted);
+ addSupertype(substituted);
}
supertypes = supertypes.tail;
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
deleted file mode 100644
index e69de29..0000000
--- a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
+++ /dev/null
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 650a69d..2519c4f 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -239,7 +239,7 @@
}
HInstruction parameter = builder.addParameter(
parameterElement,
- new HType.inferredTypeForElement(parameterElement, compiler));
+ TypeMaskFactory.inferredTypeForElement(parameterElement, compiler));
builder.parameters[parameterElement] = parameter;
directLocals[parameterElement] = parameter;
});
@@ -303,7 +303,7 @@
// Unlike `this`, receiver is nullable since direct calls to generative
// constructor call the constructor with `null`.
HParameterValue value =
- new HParameterValue(parameter, new HType.exact(cls, compiler));
+ new HParameterValue(parameter, new TypeMask.exact(cls));
builder.graph.explicitReceiverParameter = value;
builder.graph.entry.addAtEntry(value);
}
@@ -369,8 +369,12 @@
} else if (isStoredInClosureField(element)) {
Element redirect = redirectionMapping[element];
HInstruction receiver = readLocal(closureData.closureElement);
- HInstruction fieldGet = new HFieldGet(
- redirect, receiver, builder.getTypeOfCapturedVariable(redirect));
+ TypeMask type = (element.kind == ElementKind.VARIABLE_LIST)
+ ? builder.backend.nonNullType
+ : builder.getTypeOfCapturedVariable(redirect);
+ assert(element.kind != ElementKind.VARIABLE_LIST
+ || element is BoxElement);
+ HInstruction fieldGet = new HFieldGet(redirect, receiver, type);
builder.add(fieldGet);
return fieldGet;
} else if (isBoxed(element)) {
@@ -380,7 +384,7 @@
// accessed through a closure-field.
// Calling [readLocal] makes sure we generate the correct code to get
// the box.
- assert(redirect.enclosingElement.isVariable());
+ assert(redirect.enclosingElement is BoxElement);
HInstruction box = readLocal(redirect.enclosingElement);
HInstruction lookup = new HFieldGet(
redirect, box, builder.getTypeOfCapturedVariable(redirect));
@@ -434,7 +438,7 @@
// is captured will be boxed, but the box itself will be a local.
// Inside the closure the box is stored in a closure-field and cannot
// be accessed directly.
- assert(redirect.enclosingElement.isVariable());
+ assert(redirect.enclosingElement is BoxElement);
HInstruction box = readLocal(redirect.enclosingElement);
builder.add(new HFieldSet(redirect, box, value));
} else {
@@ -1000,10 +1004,10 @@
return initialValue == null;
}
- HType cachedTypeOfThis;
+ TypeMask cachedTypeOfThis;
- HType getTypeOfThis() {
- HType result = cachedTypeOfThis;
+ TypeMask getTypeOfThis() {
+ TypeMask result = cachedTypeOfThis;
if (result == null) {
Element element = localsHandler.closureData.thisElement;
ClassElement cls = element.enclosingElement.getEnclosingClass();
@@ -1012,22 +1016,22 @@
// of the class that mixins the enclosing class. These two
// classes do not have a subclass relationship, so, for
// simplicity, we mark the type as an interface type.
- result = new HType.nonNullSubtype(cls, compiler);
+ result = new TypeMask.nonNullSubtype(cls.declaration);
} else {
- result = new HType.nonNullSubclass(cls, compiler);
+ result = new TypeMask.nonNullSubclass(cls.declaration);
}
cachedTypeOfThis = result;
}
return result;
}
- Map<Element, HType> cachedTypesOfCapturedVariables =
- new Map<Element, HType>();
+ Map<Element, TypeMask> cachedTypesOfCapturedVariables =
+ new Map<Element, TypeMask>();
- HType getTypeOfCapturedVariable(Element element) {
+ TypeMask getTypeOfCapturedVariable(Element element) {
assert(element.isField());
return cachedTypesOfCapturedVariables.putIfAbsent(element, () {
- return new HType.inferredTypeForElement(element, compiler);
+ return TypeMaskFactory.inferredTypeForElement(element, compiler);
});
}
@@ -1122,7 +1126,7 @@
return bodyElement;
}
- HParameterValue addParameter(Element element, HType type) {
+ HParameterValue addParameter(Element element, TypeMask type) {
assert(inliningStack.isEmpty);
HParameterValue result = new HParameterValue(element, type);
if (lastAddedParameter == null) {
@@ -1713,7 +1717,7 @@
includeSuperAndInjectedMembers: true);
InterfaceType type = classElement.computeType(compiler);
- HType ssaType = new HType.nonNullExact(classElement, compiler);
+ TypeMask ssaType = new TypeMask.nonNullExact(classElement.declaration);
List<DartType> instantiatedTypes;
addInlinedInstantiation(type);
if (!currentInlinedInstantiations.isEmpty) {
@@ -1886,13 +1890,13 @@
if (type == null) return original;
type = type.unalias(compiler);
if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) {
- HType subtype = new HType.subtype(type.element, compiler);
+ TypeMask subtype = new TypeMask.subtype(type.element);
HInstruction representations = buildTypeArgumentRepresentations(type);
add(representations);
return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
original, representations);
} else if (type.kind == TypeKind.TYPE_VARIABLE) {
- HType subtype = original.instructionType;
+ TypeMask subtype = original.instructionType;
HInstruction typeVariable = addTypeVariableReference(type);
return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
original, typeVariable);
@@ -1900,7 +1904,7 @@
if (backend.rti.isSimpleFunctionType(type)) {
return original.convertType(compiler, type, kind);
}
- HType subtype = original.instructionType;
+ TypeMask subtype = original.instructionType;
if (type.containsTypeVariables) {
bool contextIsTypeArguments = false;
HInstruction context;
@@ -2600,7 +2604,7 @@
}
});
- HType type = new HType.nonNullExact(compiler.functionClass, compiler);
+ TypeMask type = new TypeMask.nonNullExact(compiler.functionClass);
push(new HForeignNew(closureClassElement, type, capturedVariables));
Element methodElement = nestedClosureData.closureElement;
@@ -2740,12 +2744,13 @@
// The inferrer may have found a better type than the constant
// handler in the case of lists, because the constant handler
// does not look at elements in the list.
- HType type = new HType.inferredTypeForElement(element, compiler);
+ TypeMask type =
+ TypeMaskFactory.inferredTypeForElement(element, compiler);
if (!type.containsAll(compiler)) instruction.instructionType = type;
} else if (element.isField() && isLazilyInitialized(element)) {
HInstruction instruction = new HLazyStatic(
element,
- new HType.inferredTypeForElement(element, compiler));
+ TypeMaskFactory.inferredTypeForElement(element, compiler));
push(instruction);
} else {
if (element.isGetter()) {
@@ -2755,7 +2760,7 @@
// creating an [HStatic].
HInstruction instruction = new HStatic(
element.declaration,
- new HType.inferredTypeForElement(element, compiler));
+ TypeMaskFactory.inferredTypeForElement(element, compiler));
push(instruction);
}
}
@@ -2848,7 +2853,7 @@
}
HForeign createForeign(js.Expression code,
- HType type,
+ TypeMask type,
List<HInstruction> inputs) {
return new HForeign(code, type, inputs);
}
@@ -3151,7 +3156,8 @@
List<HInstruction> inputs = <HInstruction>[];
addGenericSendArgumentsToList(link.tail.tail, inputs);
- HType ssaType = new HType.fromNativeBehavior(nativeBehavior, compiler);
+ TypeMask ssaType =
+ TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
push(new HForeign(nativeBehavior.codeAst, ssaType, inputs,
effects: nativeBehavior.sideEffects,
nativeBehavior: nativeBehavior));
@@ -3652,31 +3658,42 @@
handleNewSend(NewExpression node) {
Send send = node.send;
bool isListConstructor = false;
+ bool isFixedList = false;
- HType computeType(element) {
+ TypeMask computeType(element) {
Element originalElement = elements[send];
if (Elements.isFixedListConstructorCall(originalElement, send, compiler)
|| Elements.isFilledListConstructorCall(
originalElement, send, compiler)) {
isListConstructor = true;
- HType inferred =
- new HType.inferredForNode(currentElement, send, compiler);
+ isFixedList = true;
+ TypeMask inferred =
+ TypeMaskFactory.inferredForNode(currentElement, send, compiler);
return inferred.containsAll(compiler)
? backend.fixedArrayType
: inferred;
} else if (Elements.isGrowableListConstructorCall(
originalElement, send, compiler)) {
isListConstructor = true;
- HType inferred =
- new HType.inferredForNode(currentElement, send, compiler);
+ TypeMask inferred =
+ TypeMaskFactory.inferredForNode(currentElement, send, compiler);
return inferred.containsAll(compiler)
? backend.extendableArrayType
: inferred;
+ } else if (Elements.isConstructorOfTypedArraySubclass(
+ originalElement, compiler)) {
+ isFixedList = true;
+ TypeMask inferred =
+ TypeMaskFactory.inferredForNode(currentElement, send, compiler);
+ ClassElement cls = element.getEnclosingClass();
+ return inferred.containsAll(compiler)
+ ? new TypeMask.nonNullExact(cls.thisType.element)
+ : inferred;
} else if (element.isGenerativeConstructor()) {
ClassElement cls = element.getEnclosingClass();
- return new HType.nonNullExact(cls.thisType.element, compiler);
+ return new TypeMask.nonNullExact(cls.thisType.element);
} else {
- return new HType.inferredReturnTypeForElement(
+ return TypeMaskFactory.inferredReturnTypeForElement(
originalElement, compiler);
}
}
@@ -3740,12 +3757,17 @@
if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) {
compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements);
}
- HType elementType = computeType(constructor);
+ TypeMask elementType = computeType(constructor);
addInlinedInstantiation(expectedType);
pushInvokeStatic(node, constructor, inputs, elementType);
removeInlinedInstantiation(expectedType);
HInstruction newInstance = stack.last;
+ if (isFixedList) {
+ JavaScriptItemCompilationContext context = work.compilationContext;
+ context.allocatedFixedLists.add(newInstance);
+ }
+
// The List constructor forwards to a Dart static method that does
// not know about the type argument. Therefore we special case
// this constructor to have the setRuntimeTypeInfo called where
@@ -4049,13 +4071,13 @@
bool isLength = selector.isGetter()
&& selector.name == "length";
if (isLength || selector.isIndex()) {
- HType type = new HType.nonNullExact(
- element.getEnclosingClass(), compiler);
- return type.isIndexable(compiler);
+ TypeMask type = new TypeMask.nonNullExact(
+ element.getEnclosingClass().declaration);
+ return type.satisfies(backend.jsIndexableClass, compiler);
} else if (selector.isIndexSet()) {
- HType type = new HType.nonNullExact(
- element.getEnclosingClass(), compiler);
- return type.isMutableIndexable(compiler);
+ TypeMask type = new TypeMask.nonNullExact(
+ element.getEnclosingClass().declaration);
+ return type.satisfies(backend.jsMutableIndexableClass, compiler);
} else {
return false;
}
@@ -4095,7 +4117,7 @@
inputs.add(invokeInterceptor(receiver));
}
inputs.addAll(arguments);
- HType type = new HType.inferredTypeForSelector(selector, compiler);
+ TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, compiler);
if (selector.isGetter()) {
bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
pushWithPosition(
@@ -4116,13 +4138,13 @@
void pushInvokeStatic(Node location,
Element element,
List<HInstruction> arguments,
- [HType type = null]) {
+ [TypeMask type = null]) {
if (tryInlineMethod(element, null, arguments, location)) {
return;
}
if (type == null) {
- type = new HType.inferredReturnTypeForElement(element, compiler);
+ type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
}
// TODO(5346): Try to avoid the need for calling [declaration] before
// creating an [HInvokeStatic].
@@ -4152,11 +4174,11 @@
}
inputs.add(receiver);
inputs.addAll(arguments);
- HType type;
+ TypeMask type;
if (!element.isGetter() && selector.isGetter()) {
- type = new HType.inferredTypeForElement(element, compiler);
+ type = TypeMaskFactory.inferredTypeForElement(element, compiler);
} else {
- type = new HType.inferredReturnTypeForElement(element, compiler);
+ type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
}
HInstruction instruction = new HInvokeSuper(
element,
@@ -4514,7 +4536,8 @@
add(instruction);
}
- HType type = new HType.inferredForNode(currentElement, node, compiler);
+ TypeMask type =
+ TypeMaskFactory.inferredForNode(currentElement, node, compiler);
if (!type.containsAll(compiler)) instruction.instructionType = type;
stack.add(instruction);
}
@@ -4711,7 +4734,7 @@
}
HLiteralList keyValuePairs = buildLiteralList(inputs);
add(keyValuePairs);
- HType mapType = new HType.nonNullSubtype(backend.mapLiteralClass, compiler);
+ TypeMask mapType = new TypeMask.nonNullSubtype(backend.mapLiteralClass);
pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType);
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 017889f..ffd4236 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -1536,10 +1536,8 @@
// type because our optimizations might end up in a state where the
// invoke dynamic knows more than the receiver.
ClassElement enclosing = node.element.getEnclosingClass();
- HType receiverType = new HType.fromMask(
- new TypeMask.nonNullExact(enclosing.declaration),
- compiler);
- return receiverType.refine(selector, compiler);
+ TypeMask receiverType = new TypeMask.nonNullExact(enclosing.declaration);
+ return new TypedSelector(receiverType, selector);
}
// If [JSInvocationMirror._invokeOn] is enabled, and this call
// might hit a `noSuchMethod`, we register an untyped selector.
@@ -1566,9 +1564,6 @@
void registerSetter(HInvokeDynamic node) {
Selector selector = getOptimizedSelectorFor(node, node.selector);
world.registerDynamicSetter(selector);
- HType valueType = node.isInterceptedCall
- ? node.inputs[2].instructionType
- : node.inputs[1].instructionType;
}
void registerGetter(HInvokeDynamic node) {
@@ -1667,21 +1662,27 @@
// We're accessing a native JavaScript property called 'length'
// on a JS String or a JS array. Therefore, the name of that
// property should not be mangled.
- if (backend.isTypedArray(
- node.receiver.instructionType.computeMask(compiler))) {
+ if (backend.isTypedArray(node.receiver.instructionType)) {
// TODO(12929): Remove this custom code for typed arrays once V8
// optimizes their length access.
// Do a call to `fetchLength` instead of accessing `length`
// directly. Because `fetchLength` is a constant we use its
// constant value instead.
- Element element = compiler.findRequiredElement(
- compiler.typedDataLibrary, 'fetchLength');
- Constant constant =
- compiler.constantHandler.getConstantForVariable(element);
- assert(invariant(element, constant != null,
- message: 'No constant computed for $element'));
- var jsConstant = backend.emitter.constantReference(constant);
- push(new js.Call(jsConstant, [pop()]), node);
+ if (node.usedBy.isEmpty) {
+ // The length access has not been removed because it is
+ // acting as a null check. For a faster null check, we use
+ // toString.
+ push(new js.PropertyAccess.field(pop(), 'toString'), node);
+ } else {
+ Element element = compiler.findRequiredElement(
+ compiler.typedDataLibrary, 'fetchLength');
+ Constant constant =
+ compiler.constantHandler.getConstantForVariable(element);
+ assert(invariant(element, constant != null,
+ message: 'No constant computed for $element'));
+ var jsConstant = backend.emitter.constantReference(constant);
+ push(new js.Call(jsConstant, [pop()]), node);
+ }
} else {
push(new js.PropertyAccess.field(pop(), 'length'), node);
}
@@ -2428,40 +2429,40 @@
}
}
- js.Expression generateTest(HInstruction input, HType checkedType) {
- TypeMask receiver = input.instructionType.computeMask(compiler);
- TypeMask mask = checkedType.computeMask(compiler);
+ js.Expression generateTest(HInstruction input, TypeMask checkedType) {
+ TypeMask receiver = input.instructionType;
// Figure out if it is beneficial to turn this into a null check.
// V8 generally prefers 'typeof' checks, but for integers and
// indexable primitives we cannot compile this test into a single
// typeof check so the null check is cheaper.
bool turnIntoNumCheck = input.isIntegerOrNull(compiler)
- && checkedType.isInteger(compiler);
+ && checkedType.containsOnlyInt(compiler);
bool turnIntoNullCheck = !turnIntoNumCheck
- && (mask.nullable() == receiver)
- && (checkedType.isInteger(compiler)
- || checkedType.isIndexablePrimitive(compiler));
+ && (checkedType.nullable() == receiver)
+ && (checkedType.containsOnlyInt(compiler)
+ || checkedType.satisfies(backend.jsIndexableClass, compiler));
js.Expression test;
if (turnIntoNullCheck) {
use(input);
test = new js.Binary("==", pop(), new js.LiteralNull());
- } else if (checkedType.isInteger(compiler) && !turnIntoNumCheck) {
+ } else if (checkedType.containsOnlyInt(compiler) && !turnIntoNumCheck) {
// input is !int
checkInt(input, '!==');
test = pop();
- } else if (checkedType.isNumber(compiler) || turnIntoNumCheck) {
+ } else if (checkedType.containsOnlyNum(compiler) || turnIntoNumCheck) {
// input is !num
checkNum(input, '!==');
test = pop();
- } else if (checkedType.isBoolean(compiler)) {
+ } else if (checkedType.containsOnlyBool(compiler)) {
// input is !bool
checkBool(input, '!==');
test = pop();
- } else if (checkedType.isString(compiler)) {
+ } else if (checkedType.containsOnlyString(compiler)) {
// input is !string
checkString(input, '!==');
test = pop();
- } else if (checkedType.isExtendableArray(compiler)) {
+ } else if (checkedType.satisfies(backend.jsExtendableArrayClass,
+ compiler)) {
// input is !Object || input is !Array || input.isFixed
checkObject(input, '!==');
js.Expression objectTest = pop();
@@ -2470,7 +2471,7 @@
checkFixedArray(input);
test = new js.Binary('||', objectTest, arrayTest);
test = new js.Binary('||', test, pop());
- } else if (checkedType.isMutableArray(compiler)) {
+ } else if (checkedType.satisfies(backend.jsMutableArrayClass, compiler)) {
// input is !Object
// || ((input is !Array || input.isImmutable)
// && input is !JsIndexingBehavior)
@@ -2485,7 +2486,7 @@
? new js.Binary('&&', notArrayOrImmutable, pop())
: notArrayOrImmutable;
test = new js.Binary('||', objectTest, notIndexing);
- } else if (checkedType.isReadableArray(compiler)) {
+ } else if (checkedType.satisfies(backend.jsArrayClass, compiler)) {
// input is !Object
// || (input is !Array && input is !JsIndexingBehavior)
checkObject(input, '!==');
@@ -2497,7 +2498,7 @@
? new js.Binary('&&', arrayTest, pop())
: arrayTest;
test = new js.Binary('||', objectTest, notIndexing);
- } else if (checkedType.isIndexablePrimitive(compiler)) {
+ } else if (checkedType.satisfies(backend.jsIndexableClass, compiler)) {
// input is !String
// && (input is !Object
// || (input is !Array && input is !JsIndexingBehavior))
@@ -2524,8 +2525,8 @@
if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) {
// An int check if the input is not int or null, is not
// sufficient for doing a argument or receiver check.
- assert(!node.checkedType.isInteger(compiler) ||
- node.checkedInput.isIntegerOrNull(compiler));
+ assert(!node.checkedType.containsOnlyInt(compiler) ||
+ node.checkedInput.isIntegerOrNull(compiler));
js.Expression test = generateTest(node.checkedInput, node.checkedType);
js.Block oldContainer = currentContainer;
js.Statement body = new js.Block.empty();
@@ -2582,11 +2583,10 @@
// complex expression is required.
if ((left.isConstant() && left.isConstantSentinel()) ||
(right.isConstant() && right.isConstantSentinel())) return '===';
- HType leftType = left.instructionType;
- HType rightType = right.instructionType;
- if (leftType.canBeNull() && rightType.canBeNull()) {
+ if (left.canBeNull() && right.canBeNull()) {
if (left.isConstantNull() || right.isConstantNull() ||
- (leftType.isPrimitive(compiler) && leftType == rightType)) {
+ (left.isPrimitive(compiler) &&
+ left.instructionType == right.instructionType)) {
return '==';
}
return null;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index 0f89282..a0bfc14 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -64,14 +64,14 @@
return false;
}
- bool canUseSelfForInterceptor(HType receiverType,
+ bool canUseSelfForInterceptor(HInstruction instruction,
Set<ClassElement> interceptedClasses) {
JavaScriptBackend backend = compiler.backend;
- if (receiverType.canBePrimitive(compiler)) {
+ if (instruction.canBePrimitive(compiler)) {
// Primitives always need interceptors.
return false;
}
- if (receiverType.canBeNull()
+ if (instruction.canBeNull()
&& interceptedClasses.contains(backend.jsNullClass)) {
// Need the JSNull interceptor.
return false;
@@ -80,14 +80,13 @@
// [interceptedClasses] is sparse - it is just the classes that define some
// intercepted method. Their subclasses (that inherit the method) are
// implicit, so we have to extend them.
-
- TypeMask receiverMask = receiverType.computeMask(compiler);
+ TypeMask receiverType = instruction.instructionType;
return interceptedClasses
.where((cls) => cls != compiler.objectClass)
.map((cls) => backend.classesMixedIntoNativeClasses.contains(cls)
? new TypeMask.subtype(cls)
: new TypeMask.subclass(cls))
- .every((mask) => receiverMask.intersection(mask, compiler).isEmpty);
+ .every((mask) => receiverType.intersection(mask, compiler).isEmpty);
}
HInstruction tryComputeConstantInterceptor(
@@ -100,24 +99,23 @@
return graph.thisInstruction;
}
- HType type = input.instructionType;
ClassElement constantInterceptor;
JavaScriptBackend backend = compiler.backend;
- if (type.canBeNull()) {
- if (type.isNull()) {
+ if (input.canBeNull()) {
+ if (input.isNull()) {
constantInterceptor = backend.jsNullClass;
}
- } else if (type.isInteger(compiler)) {
+ } else if (input.isInteger(compiler)) {
constantInterceptor = backend.jsIntClass;
- } else if (type.isDouble(compiler)) {
+ } else if (input.isDouble(compiler)) {
constantInterceptor = backend.jsDoubleClass;
- } else if (type.isBoolean(compiler)) {
+ } else if (input.isBoolean(compiler)) {
constantInterceptor = backend.jsBoolClass;
- } else if (type.isString(compiler)) {
+ } else if (input.isString(compiler)) {
constantInterceptor = backend.jsStringClass;
- } else if (type.isArray(compiler)) {
+ } else if (input.isArray(compiler)) {
constantInterceptor = backend.jsArrayClass;
- } else if (type.isNumber(compiler)
+ } else if (input.isNumber(compiler)
&& !interceptedClasses.contains(backend.jsIntClass)
&& !interceptedClasses.contains(backend.jsDoubleClass)) {
// If the method being intercepted is not defined in [int] or [double] we
@@ -136,7 +134,7 @@
// for a subclass or call methods defined on a subclass. Provided the
// code is completely insensitive to the specific instance subclasses, we
// can use the non-leaf class directly.
- ClassElement element = type.computeMask(compiler).singleClass(compiler);
+ ClassElement element = input.instructionType.singleClass(compiler);
if (element != null && element.isNative()) {
constantInterceptor = element;
}
@@ -216,8 +214,7 @@
}
HInstruction receiver = node.receiver;
- HType instructionType = receiver.instructionType;
- if (canUseSelfForInterceptor(instructionType, interceptedClasses)) {
+ if (canUseSelfForInterceptor(receiver, interceptedClasses)) {
node.block.rewrite(node, receiver);
return false;
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
index d2e54d0..b0ed907 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
@@ -13,10 +13,10 @@
class InvokeDynamicSpecializer {
const InvokeDynamicSpecializer();
- HType computeTypeFromInputTypes(HInvokeDynamic instruction,
- Compiler compiler) {
+ TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+ Compiler compiler) {
Selector selector = instruction.selector;
- HType type = new HType.inferredTypeForSelector(selector, compiler);
+ TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, compiler);
// TODO(ngeoffray): Because we don't know yet the side effects of
// a JS call, we sometimes know more in the compiler about the
// side effects of an element (for example operator% on the int
@@ -108,15 +108,16 @@
HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
Compiler compiler) {
- if (!instruction.inputs[1].isIndexable(compiler)) return null;
+ if (!instruction.inputs[1].isIndexablePrimitive(compiler)) return null;
if (!instruction.inputs[2].isInteger(compiler)
&& compiler.enableTypeAssertions) {
// We want the right checked mode error.
return null;
}
- HType receiverType = instruction.getDartReceiver(compiler).instructionType;
- Selector refined = receiverType.refine(instruction.selector, compiler);
- HType type = new HType.inferredTypeForSelector(refined, compiler);
+ TypeMask receiverType =
+ instruction.getDartReceiver(compiler).instructionType;
+ Selector refined = new TypedSelector(receiverType, instruction.selector);
+ TypeMask type = TypeMaskFactory.inferredTypeForSelector(refined, compiler);
return new HIndex(
instruction.inputs[1], instruction.inputs[2],
instruction.selector, type);
@@ -130,8 +131,8 @@
return constantSystem.bitNot;
}
- HType computeTypeFromInputTypes(HInvokeDynamic instruction,
- Compiler compiler) {
+ TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+ Compiler compiler) {
// All bitwise operations on primitive types either produce an
// integer or throw an error.
JavaScriptBackend backend = compiler.backend;
@@ -159,10 +160,10 @@
return constantSystem.negate;
}
- HType computeTypeFromInputTypes(HInvokeDynamic instruction,
- Compiler compiler) {
- HType operandType = instruction.inputs[1].instructionType;
- if (operandType.isNumberOrNull(compiler)) return operandType;
+ TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+ Compiler compiler) {
+ TypeMask operandType = instruction.inputs[1].instructionType;
+ if (instruction.inputs[1].isNumberOrNull(compiler)) return operandType;
return super.computeTypeFromInputTypes(instruction, compiler);
}
@@ -179,8 +180,8 @@
abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
const BinaryArithmeticSpecializer();
- HType computeTypeFromInputTypes(HInvokeDynamic instruction,
- Compiler compiler) {
+ TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+ Compiler compiler) {
HInstruction left = instruction.inputs[1];
HInstruction right = instruction.inputs[2];
JavaScriptBackend backend = compiler.backend;
@@ -241,8 +242,8 @@
return constantSystem.divide;
}
- HType computeTypeFromInputTypes(HInstruction instruction,
- Compiler compiler) {
+ TypeMask computeTypeFromInputTypes(HInstruction instruction,
+ Compiler compiler) {
HInstruction left = instruction.inputs[1];
JavaScriptBackend backend = compiler.backend;
if (left.isNumberOrNull(compiler)) {
@@ -321,8 +322,8 @@
abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
const BinaryBitOpSpecializer();
- HType computeTypeFromInputTypes(HInvokeDynamic instruction,
- Compiler compiler) {
+ TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+ Compiler compiler) {
// All bitwise operations on primitive types either produce an
// integer or throw an error.
HInstruction left = instruction.inputs[1];
@@ -434,10 +435,10 @@
abstract class RelationalSpecializer extends InvokeDynamicSpecializer {
const RelationalSpecializer();
- HType computeTypeFromInputTypes(HInvokeDynamic instruction,
- Compiler compiler) {
+ TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+ Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- if (instruction.inputs[1].instructionType.isPrimitiveOrNull(compiler)) {
+ if (instruction.inputs[1].isPrimitiveOrNull(compiler)) {
return backend.boolType;
}
return super.computeTypeFromInputTypes(instruction, compiler);
@@ -463,11 +464,12 @@
Compiler compiler) {
HInstruction left = instruction.inputs[1];
HInstruction right = instruction.inputs[2];
- HType instructionType = left.instructionType;
- if (right.isConstantNull() || instructionType.isPrimitiveOrNull(compiler)) {
+ TypeMask instructionType = left.instructionType;
+ if (right.isConstantNull() || left.isPrimitiveOrNull(compiler)) {
return newBuiltinVariant(instruction, compiler);
}
- Selector selector = instructionType.refine(instruction.selector, compiler);
+ Selector selector =
+ new TypedSelector(instructionType, instruction.selector);
World world = compiler.world;
JavaScriptBackend backend = compiler.backend;
Iterable<Element> matches = world.allFunctions.filter(selector);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 3282eb0..cdc75a2 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -161,7 +161,8 @@
return result;
}
- static HType mapConstantTypeToSsaType(Constant constant, Compiler compiler) {
+ static TypeMask mapConstantTypeToSsaType(Constant constant,
+ Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
if (constant.isNull()) return backend.nullType;
if (constant.isBool()) return backend.boolType;
@@ -177,14 +178,13 @@
if (backend.isInterceptorClass(objectConstant.type.element)) {
return backend.nonNullType;
}
- TypeMask mask = new TypeMask.nonNullExact(objectConstant.type.element);
- return new HBoundedType(mask);
+ return new TypeMask.nonNullExact(objectConstant.type.element);
}
HConstant addConstant(Constant constant, Compiler compiler) {
HConstant result = constants[constant];
if (result == null) {
- HType type = mapConstantTypeToSsaType(constant, compiler);
+ TypeMask type = mapConstantTypeToSsaType(constant, compiler);
result = new HConstant.internal(constant, type);
entry.addAtExit(result);
constants[constant] = result;
@@ -752,8 +752,6 @@
}
}
-const HType EMPTY_TYPE = const HBoundedType(const TypeMask.nonNullEmpty());
-
abstract class HInstruction implements Spannable {
Element sourceElement;
SourceFileLocation sourcePosition;
@@ -840,57 +838,136 @@
// Does this node potentially affect control flow.
bool isControlFlow() => false;
- // All isFunctions work on the propagated types.
- bool isArray(Compiler compiler) =>
- instructionType.isArray(compiler);
- bool isReadableArray(Compiler compiler) =>
- instructionType.isReadableArray(compiler);
- bool isMutableArray(Compiler compiler) =>
- instructionType.isMutableArray(compiler);
- bool isExtendableArray(Compiler compiler) =>
- instructionType.isExtendableArray(compiler);
- bool isFixedArray(Compiler compiler) =>
- instructionType.isFixedArray(compiler);
- bool isString(Compiler compiler) =>
- instructionType.isString(compiler);
- bool isPrimitive(Compiler compiler) =>
- instructionType.isPrimitive(compiler);
- bool isPrimitiveOrNull(Compiler compiler) =>
- instructionType.isPrimitiveOrNull(compiler);
- bool isBoolean(Compiler compiler) =>
- instructionType.isBoolean(compiler);
- bool isInteger(Compiler compiler) =>
- instructionType.isInteger(compiler);
- bool isIntegerOrNull(Compiler compiler) =>
- instructionType.isIntegerOrNull(compiler);
- bool isDouble(Compiler compiler) =>
- instructionType.isDouble(compiler);
- bool isDoubleOrNull(Compiler compiler) =>
- instructionType.isDoubleOrNull(compiler);
- bool isNumber(Compiler compiler) =>
- instructionType.isNumber(compiler);
- bool isNumberOrNull(Compiler compiler) =>
- instructionType.isNumberOrNull(compiler);
- bool isNull() => instructionType.isNull();
- bool canBeNull() => instructionType.canBeNull();
- bool canBePrimitive(Compiler compiler) =>
- instructionType.canBePrimitive(compiler);
- bool canBePrimitiveArray(Compiler compiler) =>
- instructionType.canBePrimitiveArray(compiler);
+ bool isExact() => instructionType.isExact || isNull();
- bool isIndexable(Compiler compiler) =>
- instructionType.isIndexable(compiler);
- bool isMutableIndexable(Compiler compiler) =>
- instructionType.isMutableIndexable(compiler);
+ bool canBeNull() => instructionType.isNullable;
- // TODO(kasperl): Get rid of this one.
- bool isIndexablePrimitive(Compiler compiler) =>
- instructionType.isIndexablePrimitive(compiler);
+ bool isNull() => instructionType.isEmpty && instructionType.isNullable;
+ bool isConflicting() {
+ return instructionType.isEmpty && !instructionType.isNullable;
+ }
+
+ bool canBePrimitive(Compiler compiler) {
+ return canBePrimitiveNumber(compiler)
+ || canBePrimitiveArray(compiler)
+ || canBePrimitiveBoolean(compiler)
+ || canBePrimitiveString(compiler)
+ || isNull();
+ }
+
+ bool canBePrimitiveNumber(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.contains(backend.jsNumberClass, compiler)
+ || instructionType.contains(backend.jsIntClass, compiler)
+ || instructionType.contains(backend.jsDoubleClass, compiler);
+ }
+
+ bool canBePrimitiveBoolean(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.contains(backend.jsBoolClass, compiler);
+ }
+
+ bool canBePrimitiveArray(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.contains(backend.jsArrayClass, compiler)
+ || instructionType.contains(backend.jsFixedArrayClass, compiler)
+ || instructionType.contains(backend.jsExtendableArrayClass, compiler);
+ }
+
+ bool isIndexablePrimitive(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.containsOnlyString(compiler)
+ || instructionType.satisfies(backend.jsIndexableClass, compiler);
+ }
+
+ bool isFixedArray(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.containsOnly(backend.jsFixedArrayClass);
+ }
+
+ bool isExtendableArray(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.containsOnly(backend.jsExtendableArrayClass);
+ }
+
+ bool isMutableArray(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.satisfies(backend.jsMutableArrayClass, compiler);
+ }
+
+ bool isReadableArray(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.satisfies(backend.jsArrayClass, compiler);
+ }
+
+ bool isMutableIndexable(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.satisfies(backend.jsMutableIndexableClass, compiler);
+ }
+
+ bool isArray(Compiler compiler) => isReadableArray(compiler);
+
+ bool canBePrimitiveString(Compiler compiler) {
+ JavaScriptBackend backend = compiler.backend;
+ return instructionType.contains(backend.jsStringClass, compiler);
+ }
+
+ bool isInteger(Compiler compiler) {
+ return instructionType.containsOnlyInt(compiler)
+ && !instructionType.isNullable;
+ }
+
+ bool isIntegerOrNull(Compiler compiler) {
+ return instructionType.containsOnlyInt(compiler);
+ }
+
+ bool isNumber(Compiler compiler) {
+ return instructionType.containsOnlyNum(compiler)
+ && !instructionType.isNullable;
+ }
+
+ bool isNumberOrNull(Compiler compiler) {
+ return instructionType.containsOnlyNum(compiler);
+ }
+
+ bool isDouble(Compiler compiler) {
+ return instructionType.containsOnlyDouble(compiler)
+ && !instructionType.isNullable;
+ }
+
+ bool isDoubleOrNull(Compiler compiler) {
+ return instructionType.containsOnlyDouble(compiler);
+ }
+
+ bool isBoolean(Compiler compiler) {
+ return instructionType.containsOnlyBool(compiler)
+ && !instructionType.isNullable;
+ }
+
+ bool isBooleanOrNull(Compiler compiler) {
+ return instructionType.containsOnlyBool(compiler);
+ }
+
+ bool isString(Compiler compiler) {
+ return instructionType.containsOnlyString(compiler);
+ }
+
+ bool isPrimitive(Compiler compiler) {
+ return (isPrimitiveOrNull(compiler) && !instructionType.isNullable)
+ || isNull();
+ }
+
+ bool isPrimitiveOrNull(Compiler compiler) {
+ return isIndexablePrimitive(compiler)
+ || isNumberOrNull(compiler)
+ || isBooleanOrNull(compiler)
+ || isNull();
+ }
/**
* Type of the unstruction.
*/
- HType instructionType;
+ TypeMask instructionType;
Selector get selector => null;
HInstruction getDartReceiver(Compiler compiler) => null;
@@ -1140,7 +1217,7 @@
} else if (kind == HTypeConversion.CHECKED_MODE_CHECK && !type.treatAsRaw) {
throw 'creating compound check to $type (this = ${this})';
} else {
- HType subtype = new HType.subtype(element, compiler);
+ TypeMask subtype = new TypeMask.subtype(element.declaration);
return new HTypeConversion(type, kind, subtype, this);
}
}
@@ -1155,7 +1232,7 @@
}
class HBoolify extends HInstruction {
- HBoolify(HInstruction value, HType type)
+ HBoolify(HInstruction value, TypeMask type)
: super(<HInstruction>[value], type) {
setUseGvn();
}
@@ -1218,7 +1295,7 @@
}
abstract class HControlFlow extends HInstruction {
- HControlFlow(inputs) : super(inputs, EMPTY_TYPE);
+ HControlFlow(inputs) : super(inputs, const TypeMask.nonNullEmpty());
bool isControlFlow() => true;
bool isJsStatement() => true;
}
@@ -1255,7 +1332,7 @@
HInvokeDynamic(Selector selector,
this.element,
List<HInstruction> inputs,
- HType type,
+ TypeMask type,
[bool isIntercepted = false])
: super(inputs, type),
this.selector = selector,
@@ -1287,7 +1364,7 @@
}
class HInvokeClosure extends HInvokeDynamic {
- HInvokeClosure(Selector selector, List<HInstruction> inputs, HType type)
+ HInvokeClosure(Selector selector, List<HInstruction> inputs, TypeMask type)
: super(selector, null, inputs, type) {
assert(selector.isClosureCall());
}
@@ -1297,7 +1374,7 @@
class HInvokeDynamicMethod extends HInvokeDynamic {
HInvokeDynamicMethod(Selector selector,
List<HInstruction> inputs,
- HType type,
+ TypeMask type,
[bool isIntercepted = false])
: super(selector, null, inputs, type, isIntercepted);
@@ -1316,7 +1393,7 @@
final bool isSideEffectFree;
HInvokeDynamicField(
Selector selector, Element element, List<HInstruction> inputs,
- HType type, this.isSideEffectFree)
+ TypeMask type, this.isSideEffectFree)
: super(selector, element, inputs, type);
toString() => 'invoke dynamic field: $selector';
}
@@ -1362,7 +1439,7 @@
List<DartType> instantiatedTypes;
/** The first input must be the target. */
- HInvokeStatic(this.element, inputs, HType type) : super(inputs, type);
+ HInvokeStatic(this.element, inputs, TypeMask type) : super(inputs, type);
toString() => 'invoke static: ${element.name}';
accept(HVisitor visitor) => visitor.visitInvokeStatic(this);
@@ -1406,7 +1483,7 @@
abstract class HFieldAccess extends HInstruction {
final Element element;
- HFieldAccess(Element element, List<HInstruction> inputs, HType type)
+ HFieldAccess(Element element, List<HInstruction> inputs, TypeMask type)
: this.element = element, super(inputs, type);
HInstruction get receiver => inputs[0];
@@ -1417,7 +1494,7 @@
HFieldGet(Element element,
HInstruction receiver,
- HType type,
+ TypeMask type,
{bool isAssignable})
: this.isAssignable = (isAssignable != null)
? isAssignable
@@ -1459,7 +1536,8 @@
HFieldSet(Element element,
HInstruction receiver,
HInstruction value)
- : super(element, <HInstruction>[receiver, value], EMPTY_TYPE) {
+ : super(element, <HInstruction>[receiver, value],
+ const TypeMask.nonNullEmpty()) {
sideEffects.clearAllSideEffects();
sideEffects.setChangesInstanceProperty();
}
@@ -1479,7 +1557,7 @@
class HLocalGet extends HFieldAccess {
// No need to use GVN for a [HLocalGet], it is just a local
// access.
- HLocalGet(Element element, HLocalValue local, HType type)
+ HLocalGet(Element element, HLocalValue local, TypeMask type)
: super(element, <HInstruction>[local], type);
accept(HVisitor visitor) => visitor.visitLocalGet(this);
@@ -1489,7 +1567,8 @@
class HLocalSet extends HFieldAccess {
HLocalSet(Element element, HLocalValue local, HInstruction value)
- : super(element, <HInstruction>[local, value], EMPTY_TYPE);
+ : super(element, <HInstruction>[local, value],
+ const TypeMask.nonNullEmpty());
accept(HVisitor visitor) => visitor.visitLocalSet(this);
@@ -1504,7 +1583,7 @@
final native.NativeBehavior nativeBehavior;
HForeign(this.codeAst,
- HType type,
+ TypeMask type,
List<HInstruction> inputs,
{this.isStatement: false,
SideEffects effects,
@@ -1519,7 +1598,7 @@
HForeign.statement(codeAst, List<HInstruction> inputs,
SideEffects effects,
native.NativeBehavior nativeBehavior,
- HType type)
+ TypeMask type)
: this(codeAst, type, inputs, isStatement: true,
effects: effects, nativeBehavior: nativeBehavior);
@@ -1540,7 +1619,7 @@
/// the type arguments. See also [SsaBuilder.currentInlinedInstantiations].
List<DartType> instantiatedTypes;
- HForeignNew(this.element, HType type, List<HInstruction> inputs,
+ HForeignNew(this.element, TypeMask type, List<HInstruction> inputs,
[this.instantiatedTypes])
: super(null, type, inputs);
@@ -1835,7 +1914,7 @@
class HConstant extends HInstruction {
final Constant constant;
- HConstant.internal(this.constant, HType constantType)
+ HConstant.internal(this.constant, TypeMask constantType)
: super(<HInstruction>[], constantType);
toString() => 'literal: $constant';
@@ -1860,7 +1939,7 @@
}
class HNot extends HInstruction {
- HNot(HInstruction value, HType type) : super(<HInstruction>[value], type) {
+ HNot(HInstruction value, TypeMask type) : super(<HInstruction>[value], type) {
setUseGvn();
}
@@ -1876,7 +1955,7 @@
* value from the start, whereas [HLocalValue]s need to be initialized first.
*/
class HLocalValue extends HInstruction {
- HLocalValue(Element element, HType type) : super(<HInstruction>[], type) {
+ HLocalValue(Element element, TypeMask type) : super(<HInstruction>[], type) {
sourceElement = element;
}
@@ -1892,7 +1971,7 @@
}
class HThis extends HParameterValue {
- HThis(Element element, HType type) : super(element, type);
+ HThis(Element element, TypeMask type) : super(element, type);
toString() => 'this';
accept(HVisitor visitor) => visitor.visitThis(this);
bool isCodeMotionInvariant() => true;
@@ -1912,15 +1991,15 @@
// The order of the [inputs] must correspond to the order of the
// predecessor-edges. That is if an input comes from the first predecessor
// of the surrounding block, then the input must be the first in the [HPhi].
- HPhi(Element element, List<HInstruction> inputs, HType type)
+ HPhi(Element element, List<HInstruction> inputs, TypeMask type)
: super(inputs, type) {
sourceElement = element;
}
- HPhi.noInputs(Element element, HType type)
+ HPhi.noInputs(Element element, TypeMask type)
: this(element, <HInstruction>[], type);
- HPhi.singleInput(Element element, HInstruction input, HType type)
+ HPhi.singleInput(Element element, HInstruction input, TypeMask type)
: this(element, <HInstruction>[input], type);
- HPhi.manyInputs(Element element, List<HInstruction> inputs, HType type)
+ HPhi.manyInputs(Element element, List<HInstruction> inputs, TypeMask type)
: this(element, inputs, type);
void addInput(HInstruction input) {
@@ -2011,7 +2090,8 @@
}
class HThrowExpression extends HInstruction {
- HThrowExpression(value) : super(<HInstruction>[value], EMPTY_TYPE);
+ HThrowExpression(value)
+ : super(<HInstruction>[value], const TypeMask.nonNullEmpty());
toString() => 'throw expression';
accept(HVisitor visitor) => visitor.visitThrowExpression(this);
bool canThrow() => true;
@@ -2049,7 +2129,7 @@
// This field should originally be null to allow GVN'ing all
// [HInterceptor] on the same input.
Set<ClassElement> interceptedClasses;
- HInterceptor(HInstruction receiver, HType type)
+ HInterceptor(HInstruction receiver, TypeMask type)
: super(<HInstruction>[receiver], type) {
sideEffects.clearAllSideEffects();
setUseGvn();
@@ -2081,11 +2161,11 @@
Set<ClassElement> interceptedClasses;
HOneShotInterceptor(Selector selector,
List<HInstruction> inputs,
- HType type,
+ TypeMask type,
this.interceptedClasses)
: super(selector, null, inputs, type, true) {
assert(inputs[0] is HConstant);
- assert(inputs[0].instructionType.isNull());
+ assert(inputs[0].isNull());
}
bool isCallOnInterceptor(Compiler compiler) => true;
@@ -2115,7 +2195,7 @@
class HStaticStore extends HInstruction {
Element element;
HStaticStore(this.element, HInstruction value)
- : super(<HInstruction>[value], EMPTY_TYPE) {
+ : super(<HInstruction>[value], const TypeMask.nonNullEmpty()) {
sideEffects.clearAllSideEffects();
sideEffects.setChangesStaticProperty();
}
@@ -2129,7 +2209,7 @@
}
class HLiteralList extends HInstruction {
- HLiteralList(List<HInstruction> inputs, HType type) : super(inputs, type);
+ HLiteralList(List<HInstruction> inputs, TypeMask type) : super(inputs, type);
toString() => 'literal list';
accept(HVisitor visitor) => visitor.visitLiteralList(this);
}
@@ -2171,7 +2251,8 @@
HInstruction index,
HInstruction value,
this.selector)
- : super(<HInstruction>[receiver, index, value], EMPTY_TYPE) {
+ : super(<HInstruction>[receiver, index, value],
+ const TypeMask.nonNullEmpty()) {
sideEffects.clearAllSideEffects();
sideEffects.setChangesIndex();
}
@@ -2199,26 +2280,26 @@
HIs.direct(DartType typeExpression,
HInstruction expression,
- HType type)
+ TypeMask type)
: this.internal(typeExpression, [expression], RAW_CHECK, type);
HIs.raw(DartType typeExpression,
HInstruction expression,
HInterceptor interceptor,
- HType type)
+ TypeMask type)
: this.internal(
typeExpression, [expression, interceptor], RAW_CHECK, type);
HIs.compound(DartType typeExpression,
HInstruction expression,
HInstruction call,
- HType type)
+ TypeMask type)
: this.internal(typeExpression, [expression, call], COMPOUND_CHECK, type);
HIs.variable(DartType typeExpression,
HInstruction expression,
HInstruction call,
- HType type)
+ TypeMask type)
: this.internal(typeExpression, [expression, call], VARIABLE_CHECK, type);
HIs.internal(this.typeExpression, List<HInstruction> inputs, this.kind, type)
@@ -2262,7 +2343,7 @@
final int kind;
final Selector receiverTypeCheckSelector;
final bool contextIsTypeArguments;
- HType checkedType; // Not final because we refine it.
+ TypeMask checkedType; // Not final because we refine it.
static const int CHECKED_MODE_CHECK = 0;
static const int ARGUMENT_TYPE_CHECK = 1;
@@ -2271,7 +2352,7 @@
static const int RECEIVER_TYPE_CHECK = 4;
HTypeConversion(this.typeExpression, this.kind,
- HType type, HInstruction input,
+ TypeMask type, HInstruction input,
[this.receiverTypeCheckSelector])
: contextIsTypeArguments = false,
checkedType = type,
@@ -2283,7 +2364,7 @@
}
HTypeConversion.withTypeRepresentation(this.typeExpression, this.kind,
- HType type, HInstruction input,
+ TypeMask type, HInstruction input,
HInstruction typeRepresentation)
: contextIsTypeArguments = false,
checkedType = type,
@@ -2294,7 +2375,7 @@
}
HTypeConversion.withContext(this.typeExpression, this.kind,
- HType type, HInstruction input,
+ TypeMask type, HInstruction input,
HInstruction context,
{bool this.contextIsTypeArguments})
: super(<HInstruction>[input, context], type),
@@ -2346,8 +2427,8 @@
/// The [HTypeKnown] instruction marks a value with a refined type.
class HTypeKnown extends HCheck {
- HType knownType;
- HTypeKnown(HType knownType, HInstruction input)
+ TypeMask knownType;
+ HTypeKnown(TypeMask knownType, HInstruction input)
: this.knownType = knownType,
super(<HInstruction>[input], knownType);
toString() => 'TypeKnown $knownType';
@@ -2377,7 +2458,7 @@
class HStringConcat extends HInstruction {
final Node node;
- HStringConcat(HInstruction left, HInstruction right, this.node, HType type)
+ HStringConcat(HInstruction left, HInstruction right, this.node, TypeMask type)
: super(<HInstruction>[left, right], type) {
// TODO(sra): Until Issue 9293 is fixed, this false dependency keeps the
// concats bunched with stringified inputs for much better looking code with
@@ -2398,7 +2479,7 @@
*/
class HStringify extends HInstruction {
final Node node;
- HStringify(HInstruction input, this.node, HType type)
+ HStringify(HInstruction input, this.node, TypeMask type)
: super(<HInstruction>[input], type) {
sideEffects.setAllSideEffects();
sideEffects.setDependsOnSomething();
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index d3e21fd..6b83cda 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -109,7 +109,7 @@
// If we can replace [instruction] with [replacement], then
// [replacement]'s type can be narrowed.
- HType newType = replacement.instructionType.intersection(
+ TypeMask newType = replacement.instructionType.intersection(
instruction.instructionType, compiler);
replacement.instructionType = newType;
@@ -145,13 +145,10 @@
List<HInstruction> inputs = node.inputs;
assert(inputs.length == 1);
HInstruction input = inputs[0];
- HType type = input.instructionType;
- if (type.isBoolean(compiler)) return input;
+ if (input.isBoolean(compiler)) return input;
// All values that cannot be 'true' are boolified to false.
- TypeMask mask = type.computeMask(compiler);
- // TODO(kasperl): Get rid of the null check here once all HTypes
- // have a proper mask.
- if (mask != null && !mask.contains(backend.jsBoolClass, compiler)) {
+ TypeMask mask = input.instructionType;
+ if (!mask.contains(backend.jsBoolClass, compiler)) {
return graph.addConstantBool(false, compiler);
}
return node;
@@ -188,7 +185,7 @@
HInstruction tryOptimizeLengthInterceptedGetter(HInvokeDynamic node) {
HInstruction actualReceiver = node.inputs[1];
- if (actualReceiver.isIndexable(compiler)) {
+ if (actualReceiver.isIndexablePrimitive(compiler)) {
if (actualReceiver.isConstantString()) {
HConstant constantInput = actualReceiver;
StringConstant constant = constantInput.constant;
@@ -199,10 +196,19 @@
return graph.addConstantInt(constant.length, compiler);
}
Element element = backend.jsIndexableLength;
- bool isAssignable = !actualReceiver.isFixedArray(compiler) &&
- !actualReceiver.isString(compiler);
+ var mask = actualReceiver.instructionType;
+ bool isFixedLength = false;
+ if (mask.isContainer && mask.length != null) {
+ // A container on which we have inferred the length.
+ isFixedLength = true;
+ } else if (mask.containsOnly(backend.jsFixedArrayClass)
+ || mask.containsOnlyString(compiler)
+ || backend.isTypedArray(mask)) {
+ isFixedLength = true;
+ }
HFieldGet result = new HFieldGet(
- element, actualReceiver, backend.intType, isAssignable: isAssignable);
+ element, actualReceiver, backend.intType,
+ isAssignable: !isFixedLength);
return result;
} else if (actualReceiver.isConstantMap()) {
HConstant constantInput = actualReceiver;
@@ -292,8 +298,8 @@
if (folded != node) return folded;
}
- HType receiverType = node.getDartReceiver(compiler).instructionType;
- Selector selector = receiverType.refine(node.selector, compiler);
+ TypeMask receiverType = node.getDartReceiver(compiler).instructionType;
+ Selector selector = new TypedSelector(receiverType, node.selector);
Element element = compiler.world.locateSingleElement(selector);
// TODO(ngeoffray): Also fold if it's a getter or variable.
if (element != null
@@ -368,12 +374,12 @@
if (!canInline) return null;
-
// Strengthen instruction type from annotations to help optimize
// dependent instructions.
native.NativeBehavior nativeBehavior =
native.NativeBehavior.ofMethod(method, compiler);
- HType returnType = new HType.fromNativeBehavior(nativeBehavior, compiler);
+ TypeMask returnType =
+ TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
HInvokeDynamicMethod result =
new HInvokeDynamicMethod(node.selector, inputs, returnType);
result.element = method;
@@ -437,14 +443,16 @@
HInstruction handleIdentityCheck(HRelational node) {
HInstruction left = node.left;
HInstruction right = node.right;
- HType leftType = left.instructionType;
- HType rightType = right.instructionType;
+ TypeMask leftType = left.instructionType;
+ TypeMask rightType = right.instructionType;
// Intersection of int and double return conflicting, so
// we don't optimize on numbers to preserve the runtime semantics.
- if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler)) &&
- leftType.intersection(rightType, compiler).isConflicting()) {
- return graph.addConstantBool(false, compiler);
+ if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler))) {
+ TypeMask intersection = leftType.intersection(rightType, compiler);
+ if (intersection.isEmpty && !intersection.isNullable) {
+ return graph.addConstantBool(false, compiler);
+ }
}
if (left.isNull() && right.isNull()) {
@@ -527,8 +535,8 @@
return graph.addConstantBool(true, compiler);
}
- HType expressionType = node.expression.instructionType;
- if (expressionType.isInteger(compiler)) {
+ HInstruction expression = node.expression;
+ if (expression.isInteger(compiler)) {
if (identical(element, compiler.intClass)
|| identical(element, compiler.numClass)
|| Elements.isNumberOrStringSupertype(element, compiler)) {
@@ -540,7 +548,7 @@
} else {
return graph.addConstantBool(false, compiler);
}
- } else if (expressionType.isDouble(compiler)) {
+ } else if (expression.isDouble(compiler)) {
if (identical(element, compiler.doubleClass)
|| identical(element, compiler.numClass)
|| Elements.isNumberOrStringSupertype(element, compiler)) {
@@ -553,14 +561,14 @@
} else {
return graph.addConstantBool(false, compiler);
}
- } else if (expressionType.isNumber(compiler)) {
+ } else if (expression.isNumber(compiler)) {
if (identical(element, compiler.numClass)) {
return graph.addConstantBool(true, compiler);
} else {
// We cannot just return false, because the expression may be of
// type int or double.
}
- } else if (expressionType.canBePrimitiveNumber(compiler)
+ } else if (expression.canBePrimitiveNumber(compiler)
&& identical(element, compiler.intClass)) {
// We let the JS semantics decide for that check.
return node;
@@ -569,7 +577,7 @@
// a class [:A<T>:], is currently always considered to have the
// raw type.
} else if (!RuntimeTypes.hasTypeArguments(type)) {
- TypeMask expressionMask = expressionType.computeMask(compiler);
+ TypeMask expressionMask = expression.instructionType;
TypeMask typeMask = (element == compiler.nullClass)
? new TypeMask.subtype(element)
: new TypeMask.nonNullSubtype(element);
@@ -601,41 +609,36 @@
return removeIfCheckAlwaysSucceeds(node, node.knownType);
}
- HInstruction removeIfCheckAlwaysSucceeds(HCheck node, HType checkedType) {
+ HInstruction removeIfCheckAlwaysSucceeds(HCheck node, TypeMask checkedType) {
if (checkedType.containsAll(compiler)) return node;
HInstruction input = node.checkedInput;
- HType inputType = input.instructionType;
- HType filteredType = inputType.intersection(checkedType, compiler);
- return (inputType == filteredType) ? input : node;
+ TypeMask inputType = input.instructionType;
+ return inputType.isInMask(checkedType, compiler) ? input : node;
}
Element findConcreteFieldForDynamicAccess(HInstruction receiver,
Selector selector) {
- HType receiverType = receiver.instructionType;
+ TypeMask receiverType = receiver.instructionType;
return compiler.world.locateSingleField(
- receiverType.refine(selector, compiler));
+ new TypedSelector(receiverType, selector));
}
HInstruction visitFieldGet(HFieldGet node) {
var receiver = node.receiver;
if (node.element == backend.jsIndexableLength) {
- if (receiver is HInvokeStatic) {
- // Try to recognize the length getter with input
- // [:new List(int):].
- Element element = receiver.element;
+ JavaScriptItemCompilationContext context = work.compilationContext;
+ if (context.allocatedFixedLists.contains(receiver)) {
// TODO(ngeoffray): checking if the second input is an integer
// should not be necessary but it currently makes it easier for
// other optimizations to reason about a fixed length constructor
// that we know takes an int.
- if (element == compiler.unnamedListConstructor
- && receiver.inputs.length == 1
- && receiver.inputs[0].isInteger(compiler)) {
+ if (receiver.inputs[0].isInteger(compiler)) {
return receiver.inputs[0];
}
} else if (receiver.isConstantList() || receiver.isConstantString()) {
return graph.addConstantInt(receiver.constant.length, compiler);
} else {
- var type = receiver.instructionType.computeMask(compiler);
+ var type = receiver.instructionType;
if (type.isContainer && type.length != null) {
HInstruction constant = graph.addConstantInt(type.length, compiler);
if (type.isNullable) {
@@ -694,13 +697,13 @@
isAssignable = true;
}
- HType type;
+ TypeMask type;
if (field.getEnclosingClass().isNative()) {
- type = new HType.fromNativeBehavior(
+ type = TypeMaskFactory.fromNativeBehavior(
native.NativeBehavior.ofFieldLoad(field, compiler),
compiler);
} else {
- type = new HType.inferredTypeForElement(field, compiler);
+ type = TypeMaskFactory.inferredTypeForElement(field, compiler);
}
return new HFieldGet(
@@ -1467,7 +1470,7 @@
// to use [newInput] instead.
void changeUsesDominatedBy(HBasicBlock dominator,
HInstruction input,
- HType convertedType) {
+ TypeMask convertedType) {
Setlet<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first);
if (dominatedUsers.isEmpty) return;
@@ -1501,7 +1504,7 @@
if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
- HType convertedType = new HType.nonNullSubtype(element, compiler);
+ TypeMask convertedType = new TypeMask.nonNullSubtype(element);
HInstruction input = instruction.expression;
for (HIf ifUser in ifUsers) {
changeUsesDominatedBy(ifUser.thenBlock, input, convertedType);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
index f62a343..3a86a9d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
@@ -174,36 +174,35 @@
HInstructionStringifier(this.context, this.currentBlock, this.compiler);
- visit(HInstruction node) => node.accept(this);
+ visit(HInstruction node) => '${node.accept(this)} ${node.instructionType}';
String temporaryId(HInstruction instruction) {
String prefix;
- HType type = instruction.instructionType;
- if (type.isNull()) {
+ if (instruction.isNull()) {
prefix = 'u';
- } else if (type.isConflicting()) {
+ } else if (instruction.isConflicting()) {
prefix = 'c';
- } else if (type.isExtendableArray(compiler)) {
+ } else if (instruction.isExtendableArray(compiler)) {
prefix = 'e';
- } else if (type.isFixedArray(compiler)) {
+ } else if (instruction.isFixedArray(compiler)) {
prefix = 'f';
- } else if (type.isMutableArray(compiler)) {
+ } else if (instruction.isMutableArray(compiler)) {
prefix = 'm';
- } else if (type.isReadableArray(compiler)) {
+ } else if (instruction.isReadableArray(compiler)) {
prefix = 'a';
- } else if (type.isString(compiler)) {
+ } else if (instruction.isString(compiler)) {
prefix = 's';
- } else if (type.isIndexable(compiler)) {
+ } else if (instruction.isIndexablePrimitive(compiler)) {
prefix = 'r';
- } else if (type.isBoolean(compiler)) {
+ } else if (instruction.isBoolean(compiler)) {
prefix = 'b';
- } else if (type.isInteger(compiler)) {
+ } else if (instruction.isInteger(compiler)) {
prefix = 'i';
- } else if (type.isDouble(compiler)) {
+ } else if (instruction.isDouble(compiler)) {
prefix = 'd';
- } else if (type.isNumber(compiler)) {
+ } else if (instruction.isNumber(compiler)) {
prefix = 'n';
- } else if (type.containsAll(compiler)) {
+ } else if (instruction.instructionType.containsAll(compiler)) {
prefix = 'v';
} else {
prefix = 'U';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index a8e4238..4df5830 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -4,136 +4,56 @@
part of ssa;
-abstract class HType {
- const HType();
-
- /**
- * Returns an [HType] with the given type mask. The factory method
- * takes care to track whether or not the resulting type may be a
- * primitive type.
- */
- factory HType.fromMask(TypeMask mask, Compiler compiler) {
- bool isNullable = mask.isNullable;
- JavaScriptBackend backend = compiler.backend;
- if (mask.isEmpty) {
- return isNullable ? backend.nullType : backend.emptyType;
- }
-
- if (mask.containsOnlyInt(compiler)) {
- return mask.isNullable
- ? new HBoundedType(new TypeMask.exact(backend.jsIntClass))
- : backend.intType;
- } else if (mask.containsOnlyDouble(compiler)) {
- return mask.isNullable
- ? new HBoundedType(new TypeMask.exact(backend.jsDoubleClass))
- : backend.doubleType;
- } else if (mask.containsOnlyNum(compiler)
- || mask.satisfies(backend.jsNumberClass, compiler)) {
- return mask.isNullable
- ? new HBoundedType(new TypeMask.subclass(backend.jsNumberClass))
- : backend.numType;
- } else if (mask.containsOnlyString(compiler)) {
- // TODO(ngeoffray): Avoid creating [TypeMask]s with the string
- // class as base.
- return isNullable
- ? new HBoundedType(new TypeMask.exact(backend.jsStringClass))
- : backend.stringType;
- } else if (mask.containsOnlyBool(compiler)) {
- return isNullable
- ? new HBoundedType(new TypeMask.exact(backend.jsBoolClass))
- : backend.boolType;
- } else if (mask.containsOnlyNull(compiler)) {
- return backend.nullType;
- }
-
- // TODO(kasperl): A lot of the code in the system currently
- // expects the top type to be 'unknown'. I'll rework this.
- if (mask.containsAll(compiler)) {
- return isNullable ? backend.dynamicType : backend.nonNullType;
- }
-
- return new HBoundedType(mask);
- }
-
- factory HType.exact(ClassElement type, Compiler compiler) {
- TypeMask mask = new TypeMask.exact(type.declaration);
- return new HType.fromMask(mask, compiler);
- }
-
- factory HType.subclass(ClassElement type, Compiler compiler) {
- TypeMask mask = new TypeMask.subclass(type.declaration);
- return new HType.fromMask(mask, compiler);
- }
-
- factory HType.subtype(ClassElement type, Compiler compiler) {
- TypeMask mask = new TypeMask.subtype(type.declaration);
- return new HType.fromMask(mask, compiler);
- }
-
- factory HType.nonNullExact(ClassElement type, Compiler compiler) {
- TypeMask mask = new TypeMask.nonNullExact(type.declaration);
- return new HType.fromMask(mask, compiler);
- }
-
- factory HType.nonNullSubclass(ClassElement type, Compiler compiler) {
- TypeMask mask = new TypeMask.nonNullSubclass(type.declaration);
- return new HType.fromMask(mask, compiler);
- }
-
- factory HType.nonNullSubtype(ClassElement type, Compiler compiler) {
- TypeMask mask = new TypeMask.nonNullSubtype(type.declaration);
- return new HType.fromMask(mask, compiler);
- }
-
- factory HType.fromInferredType(TypeMask mask, Compiler compiler) {
+class TypeMaskFactory {
+ static TypeMask fromInferredType(TypeMask mask, Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
if (mask == null) return backend.dynamicType;
- return new HType.fromMask(mask, compiler);
+ return mask;
}
- factory HType.inferredReturnTypeForElement(
+ static TypeMask inferredReturnTypeForElement(
Element element, Compiler compiler) {
- return new HType.fromInferredType(
+ return fromInferredType(
compiler.typesTask.getGuaranteedReturnTypeOfElement(element),
compiler);
}
- factory HType.inferredTypeForElement(Element element, Compiler compiler) {
- return new HType.fromInferredType(
+ static TypeMask inferredTypeForElement(Element element, Compiler compiler) {
+ return fromInferredType(
compiler.typesTask.getGuaranteedTypeOfElement(element),
compiler);
}
- factory HType.inferredTypeForSelector(Selector selector, Compiler compiler) {
- return new HType.fromInferredType(
+ static TypeMask inferredTypeForSelector(Selector selector, Compiler compiler) {
+ return fromInferredType(
compiler.typesTask.getGuaranteedTypeOfSelector(selector),
compiler);
}
- factory HType.inferredForNode(Element owner, Node node, Compiler compiler) {
- return new HType.fromInferredType(
+ static TypeMask inferredForNode(Element owner, Node node, Compiler compiler) {
+ return fromInferredType(
compiler.typesTask.getGuaranteedTypeOfNode(owner, node),
compiler);
}
- factory HType.fromNativeBehavior(native.NativeBehavior nativeBehavior,
- Compiler compiler) {
+ static TypeMask fromNativeBehavior(native.NativeBehavior nativeBehavior,
+ Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
if (nativeBehavior.typesReturned.isEmpty) return backend.dynamicType;
- HType result = nativeBehavior.typesReturned
+ TypeMask result = nativeBehavior.typesReturned
.map((type) => fromNativeType(type, compiler))
.reduce((t1, t2) => t1.union(t2, compiler));
- assert(!result.isConflicting());
+ assert(!(result.isEmpty && !result.isNullable));
return result;
}
// [type] is either an instance of [DartType] or special objects
// like [native.SpecialType.JsObject].
- static HType fromNativeType(type, Compiler compiler) {
+ static TypeMask fromNativeType(type, Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
if (type == native.SpecialType.JsObject) {
- return new HType.nonNullExact(compiler.objectClass, compiler);
+ return new TypeMask.nonNullExact(compiler.objectClass);
} else if (type.isVoid) {
return backend.nullType;
} else if (type.element == compiler.nullClass) {
@@ -141,254 +61,11 @@
} else if (type.treatAsDynamic) {
return backend.dynamicType;
} else if (compiler.world.hasAnySubtype(type.element)) {
- return new HType.nonNullSubtype(type.element, compiler);
+ return new TypeMask.nonNullSubtype(type.element);
} else if (compiler.world.hasAnySubclass(type.element)) {
- return new HType.nonNullSubclass(type.element, compiler);
+ return new TypeMask.nonNullSubclass(type.element);
} else {
- return new HType.nonNullExact(type.element, compiler);
+ return new TypeMask.nonNullExact(type.element);
}
}
-
- bool isConflicting() => false;
- bool isExact() => false;
- bool isNull() => false;
- bool isBoolean(Compiler compiler) => false;
- bool isNumber(Compiler compiler) => false;
- bool isInteger(Compiler compiler) => false;
- bool isDouble(Compiler compiler) => false;
-
- bool isString(Compiler compiler) => false;
- bool isFixedArray(Compiler compiler) => false;
- bool isReadableArray(Compiler compiler) => false;
- bool isMutableArray(Compiler compiler) => false;
- bool isExtendableArray(Compiler compiler) => false;
- bool isPrimitive(Compiler compiler) => false;
- bool isPrimitiveOrNull(Compiler compiler) => false;
-
- bool isBooleanOrNull(Compiler compiler) => false;
- bool isNumberOrNull(Compiler compiler) => false;
- bool isIntegerOrNull(Compiler compiler) => false;
- bool isDoubleOrNull(Compiler compiler) => false;
-
- // TODO(kasperl): Get rid of this one.
- bool isIndexablePrimitive(Compiler compiler) => false;
-
- bool isIndexable(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return implementsInterface(backend.jsIndexableClass, compiler);
- }
-
- bool isMutableIndexable(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return implementsInterface(backend.jsMutableIndexableClass, compiler);
- }
-
- bool implementsInterface(ClassElement interfaceElement, Compiler compiler) {
- TypeMask mask = new TypeMask.subtype(interfaceElement);
- return mask == mask.union(computeMask(compiler), compiler);
- }
-
- bool canBeNull() => false;
- bool canBePrimitive(Compiler compiler) => false;
- bool canBePrimitiveNumber(Compiler compiler) => false;
- bool canBePrimitiveString(Compiler compiler) => false;
- bool canBePrimitiveArray(Compiler compiler) => false;
- bool canBePrimitiveBoolean(Compiler compiler) => false;
-
- /** Alias for isReadableArray. */
- bool isArray(Compiler compiler) => isReadableArray(compiler);
-
- TypeMask computeMask(Compiler compiler);
-
- Selector refine(Selector selector, Compiler compiler) {
- // TODO(kasperl): Should we check if the refinement really is more
- // specialized than the starting point?
- TypeMask mask = computeMask(compiler);
- if (selector.mask == mask) return selector;
- return new TypedSelector(mask, selector);
- }
-
- /**
- * The intersection of two types is the intersection of its values. For
- * example:
- * * INTEGER.intersect(NUMBER) => INTEGER.
- * * DOUBLE.intersect(INTEGER) => CONFLICTING.
- * * MUTABLE_ARRAY.intersect(READABLE_ARRAY) => MUTABLE_ARRAY.
- *
- * When there is no predefined type to represent the intersection returns
- * [CONFLICTING].
- *
- * An intersection with [UNKNOWN] returns the non-UNKNOWN type. An
- * intersection with [CONFLICTING] returns [CONFLICTING].
- */
- HType intersection(HType other, Compiler compiler) {
- TypeMask mask = computeMask(compiler);
- TypeMask otherMask = other.computeMask(compiler);
- TypeMask intersection = mask.intersection(otherMask, compiler);
- return new HType.fromMask(intersection, compiler);
- }
-
- /**
- * The union of two types is the union of its values. For example:
- * * INTEGER.union(NUMBER) => NUMBER.
- * * DOUBLE.union(INTEGER) => NUMBER.
- * * MUTABLE_ARRAY.union(READABLE_ARRAY) => READABLE_ARRAY.
- *
- * When there is no predefined type to represent the union returns
- * [UNKNOWN].
- *
- * A union with [UNKNOWN] returns [UNKNOWN].
- * A union of [CONFLICTING] with any other types returns the other type.
- */
- HType union(HType other, Compiler compiler) {
- TypeMask mask = computeMask(compiler);
- TypeMask otherMask = other.computeMask(compiler);
- TypeMask union = mask.union(otherMask, compiler);
- return new HType.fromMask(union, compiler);
- }
-
- HType simplify(Compiler compiler) => this;
-
- HType nonNullable(compiler) {
- return new HType.fromMask(computeMask(compiler).nonNullable(), compiler);
- }
-
- bool containsAll(Compiler compiler) {
- return computeMask(compiler).containsAll(compiler);
- }
-}
-
-class HBoundedType extends HType {
- final TypeMask mask;
- const HBoundedType(this.mask);
-
- bool isExact() => mask.isExact || isNull();
-
- bool canBeNull() => mask.isNullable;
-
- bool isNull() => mask.isEmpty && mask.isNullable;
- bool isConflicting() => mask.isEmpty && !mask.isNullable;
-
- bool canBePrimitive(Compiler compiler) {
- return canBePrimitiveNumber(compiler)
- || canBePrimitiveArray(compiler)
- || canBePrimitiveBoolean(compiler)
- || canBePrimitiveString(compiler)
- || isNull();
- }
-
- bool canBePrimitiveNumber(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return mask.contains(backend.jsNumberClass, compiler)
- || mask.contains(backend.jsIntClass, compiler)
- || mask.contains(backend.jsDoubleClass, compiler);
- }
-
- bool canBePrimitiveBoolean(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return mask.contains(backend.jsBoolClass, compiler);
- }
-
- bool canBePrimitiveArray(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return mask.contains(backend.jsArrayClass, compiler)
- || mask.contains(backend.jsFixedArrayClass, compiler)
- || mask.contains(backend.jsExtendableArrayClass, compiler);
- }
-
- bool isIndexablePrimitive(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return mask.satisfies(backend.jsIndexableClass, compiler);
- }
-
- bool isFixedArray(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return mask.containsOnly(backend.jsFixedArrayClass);
- }
-
- bool isExtendableArray(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return mask.containsOnly(backend.jsExtendableArrayClass);
- }
-
- bool isMutableArray(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return mask.satisfies(backend.jsMutableArrayClass, compiler);
- }
-
- bool isReadableArray(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return mask.satisfies(backend.jsArrayClass, compiler);
- }
-
- bool canBePrimitiveString(Compiler compiler) {
- JavaScriptBackend backend = compiler.backend;
- return mask.contains(backend.jsStringClass, compiler);
- }
-
- TypeMask computeMask(Compiler compiler) => mask;
-
- HType simplify(Compiler compiler) {
- return new HType.fromMask(mask.simplify(compiler), compiler);
- }
-
- bool isInteger(Compiler compiler) {
- return mask.containsOnlyInt(compiler) && !mask.isNullable;
- }
-
- bool isIntegerOrNull(Compiler compiler) {
- return mask.containsOnlyInt(compiler);
- }
-
- bool isNumber(Compiler compiler) {
- return mask.containsOnlyNum(compiler) && !mask.isNullable;
- }
-
- bool isNumberOrNull(Compiler compiler) {
- return mask.containsOnlyNum(compiler);
- }
-
- bool isDouble(Compiler compiler) {
- return mask.containsOnlyDouble(compiler) && !mask.isNullable;
- }
-
- bool isDoubleOrNull(Compiler compiler) {
- return mask.containsOnlyDouble(compiler);
- }
-
- bool isBoolean(Compiler compiler) {
- return mask.containsOnlyBool(compiler) && !mask.isNullable;
- }
-
- bool isBooleanOrNull(Compiler compiler) {
- return mask.containsOnlyBool(compiler);
- }
-
- bool isString(Compiler compiler) {
- return mask.containsOnlyString(compiler);
- }
-
- bool isPrimitive(Compiler compiler) {
- return (isPrimitiveOrNull(compiler) && !mask.isNullable)
- || isNull();
- }
-
- bool isPrimitiveOrNull(Compiler compiler) {
- return isIndexablePrimitive(compiler)
- || isNumberOrNull(compiler)
- || isBooleanOrNull(compiler)
- || isNull();
- }
-
- bool operator ==(other) {
- if (other is !HBoundedType) return false;
- HBoundedType bounded = other;
- return mask == bounded.mask;
- }
-
- int get hashCode => mask.hashCode;
-
- String toString() {
- return 'BoundedType(mask=$mask)';
- }
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index 60e6744..9ff28dc 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -15,7 +15,7 @@
SsaTypePropagator(this.compiler);
- HType computeType(HInstruction instruction) {
+ TypeMask computeType(HInstruction instruction) {
return instruction.accept(this);
}
@@ -23,8 +23,8 @@
// whether or not the type was changed.
bool updateType(HInstruction instruction) {
// Compute old and new types.
- HType oldType = instruction.instructionType;
- HType newType = computeType(instruction);
+ TypeMask oldType = instruction.instructionType;
+ TypeMask newType = computeType(instruction);
assert(newType != null);
// We unconditionally replace the propagated type with the new type. The
// computeType must make sure that we eventually reach a stable state.
@@ -96,7 +96,7 @@
}
}
- HType visitBinaryArithmetic(HBinaryArithmetic instruction) {
+ TypeMask visitBinaryArithmetic(HBinaryArithmetic instruction) {
HInstruction left = instruction.left;
HInstruction right = instruction.right;
JavaScriptBackend backend = compiler.backend;
@@ -107,55 +107,55 @@
return backend.numType;
}
- HType visitNegate(HNegate instruction) {
+ TypeMask visitNegate(HNegate instruction) {
return instruction.operand.instructionType;
}
- HType visitInstruction(HInstruction instruction) {
+ TypeMask visitInstruction(HInstruction instruction) {
assert(instruction.instructionType != null);
return instruction.instructionType;
}
- HType visitPhi(HPhi phi) {
+ TypeMask visitPhi(HPhi phi) {
JavaScriptBackend backend = compiler.backend;
- HType candidateType = backend.emptyType;
+ TypeMask candidateType = backend.emptyType;
for (int i = 0, length = phi.inputs.length; i < length; i++) {
- HType inputType = phi.inputs[i].instructionType;
+ TypeMask inputType = phi.inputs[i].instructionType;
candidateType = candidateType.union(inputType, compiler);
}
return candidateType;
}
- HType visitTypeConversion(HTypeConversion instruction) {
- HType inputType = instruction.checkedInput.instructionType;
- HType checkedType = instruction.checkedType;
+ TypeMask visitTypeConversion(HTypeConversion instruction) {
+ HInstruction input = instruction.checkedInput;
+ TypeMask inputType = input.instructionType;
+ TypeMask checkedType = instruction.checkedType;
JavaScriptBackend backend = compiler.backend;
if (instruction.isArgumentTypeCheck || instruction.isReceiverTypeCheck) {
// We must make sure a type conversion for receiver or argument check
// does not try to do an int check, because an int check is not enough.
// We only do an int check if the input is integer or null.
- if (checkedType.isNumber(compiler)
- && !checkedType.isDouble(compiler)
- && inputType.isIntegerOrNull(compiler)) {
+ if (checkedType.containsOnlyNum(compiler)
+ && !checkedType.containsOnlyDouble(compiler)
+ && input.isIntegerOrNull(compiler)) {
instruction.checkedType = backend.intType;
- } else if (checkedType.isInteger(compiler)
- && !inputType.isIntegerOrNull(compiler)) {
+ } else if (checkedType.containsOnlyInt(compiler)
+ && !input.isIntegerOrNull(compiler)) {
instruction.checkedType = backend.numType;
}
}
- HType outputType = checkedType.intersection(inputType, compiler);
- if (outputType.isConflicting()) {
+ TypeMask outputType = checkedType.intersection(inputType, compiler);
+ if (outputType.isEmpty && !outputType.isNullable) {
// Intersection of double and integer conflicts (is empty), but JS numbers
// can be both int and double at the same time. For example, the input
// can be a literal double '8.0' that is marked as an integer (because 'is
// int' will return 'true'). What we really need to do is make the
- // overlap between int and double values explicit in the HType system.
- if (inputType.isIntegerOrNull(compiler)
- && checkedType.isDoubleOrNull(compiler)) {
- if (inputType.canBeNull() && checkedType.canBeNull()) {
- outputType =
- new HBoundedType(new TypeMask.exact(backend.jsDoubleClass));
+ // overlap between int and double values explicit in the TypeMask system.
+ if (inputType.containsOnlyInt(compiler)
+ && checkedType.containsOnlyDouble(compiler)) {
+ if (inputType.isNullable && checkedType.isNullable) {
+ outputType = backend.doubleType.nullable();
} else {
outputType = backend.doubleType;
}
@@ -164,14 +164,14 @@
return outputType;
}
- HType visitTypeKnown(HTypeKnown instruction) {
+ TypeMask visitTypeKnown(HTypeKnown instruction) {
HInstruction input = instruction.checkedInput;
return instruction.knownType.intersection(input.instructionType, compiler);
}
void convertInput(HInvokeDynamic instruction,
HInstruction input,
- HType type,
+ TypeMask type,
int kind) {
Selector selector = (kind == HTypeConversion.RECEIVER_TYPE_CHECK)
? instruction.selector
@@ -183,15 +183,15 @@
}
bool isCheckEnoughForNsmOrAe(HInstruction instruction,
- HType type) {
+ TypeMask type) {
// In some cases, we want the receiver to be an integer,
// but that does not mean we will get a NoSuchMethodError
// if it's not: the receiver could be a double.
- if (type.isInteger(compiler)) {
+ if (type.containsOnlyInt(compiler)) {
// If the instruction's type is integer or null, the codegen
// will emit a null check, which is enough to know if it will
// hit a noSuchMethod.
- return instruction.instructionType.isIntegerOrNull(compiler);
+ return instruction.isIntegerOrNull(compiler);
}
return true;
}
@@ -205,7 +205,7 @@
if (receiver.isNumberOrNull(compiler)) {
convertInput(instruction,
receiver,
- receiver.instructionType.nonNullable(compiler),
+ receiver.instructionType.nonNullable(),
HTypeConversion.RECEIVER_TYPE_CHECK);
return true;
} else if (instruction.element == null) {
@@ -214,10 +214,15 @@
if (targets.length == 1) {
Element target = targets.first;
ClassElement cls = target.getEnclosingClass();
- HType type = new HType.nonNullSubclass(cls, compiler);
+ TypeMask type = new TypeMask.nonNullSubclass(cls.declaration);
// TODO(ngeoffray): We currently only optimize on primitive
// types.
- if (!type.isPrimitive(compiler)) return false;
+ JavaScriptBackend backend = compiler.backend;
+ if (!type.satisfies(backend.jsIndexableClass, compiler)
+ && !type.containsOnlyNum(compiler)
+ && !type.containsOnlyBool(compiler)) {
+ return false;
+ }
if (!isCheckEnoughForNsmOrAe(receiver, type)) return false;
instruction.element = target;
convertInput(instruction,
@@ -237,14 +242,13 @@
// We want the right error in checked mode.
if (compiler.enableTypeAssertions) return false;
HInstruction left = instruction.inputs[1];
- HType receiverType = left.instructionType;
-
HInstruction right = instruction.inputs[2];
+
Selector selector = instruction.selector;
- if (selector.isOperator() && receiverType.isNumber(compiler)) {
+ if (selector.isOperator() && left.isNumber(compiler)) {
if (right.isNumber(compiler)) return false;
JavaScriptBackend backend = compiler.backend;
- HType type = right.isIntegerOrNull(compiler)
+ TypeMask type = right.isIntegerOrNull(compiler)
? backend.intType
: backend.numType;
// TODO(ngeoffray): Some number operations don't have a builtin
@@ -279,7 +283,7 @@
});
}
- HType visitInvokeDynamic(HInvokeDynamic instruction) {
+ TypeMask visitInvokeDynamic(HInvokeDynamic instruction) {
if (instruction.isInterceptedCall) {
// We cannot do the following optimization now, because we have
// to wait for the type propagation to be stable. The receiver
@@ -298,36 +302,33 @@
}
HInstruction receiver = instruction.getDartReceiver(compiler);
- HType receiverType = receiver.instructionType;
- Selector selector = receiverType.refine(instruction.selector, compiler);
+ TypeMask receiverType = receiver.instructionType;
+ Selector selector = new TypedSelector(receiverType, instruction.selector);
instruction.selector = selector;
// Try to specialize the receiver after this call.
if (receiver.dominatedUsers(instruction).length != 1
&& !selector.isClosureCall()) {
- TypeMask oldMask = receiverType.computeMask(compiler);
- TypeMask newMask = compiler.world.allFunctions.receiverType(selector);
- newMask = newMask.intersection(oldMask, compiler);
-
- if (newMask != oldMask) {
- HType newType = new HType.fromMask(newMask, compiler);
- var next = instruction.next;
- if (next is HTypeKnown && next.checkedInput == receiver) {
- // We already have refined [receiver].
- HType nextType = next.instructionType;
- if (nextType != newType) {
- next.knownType = next.instructionType = newType;
- addDependentInstructionsToWorkList(next);
- }
- } else {
- // Insert a refinement node after the call and update all
- // users dominated by the call to use that node instead of
- // [receiver].
- HTypeKnown converted = new HTypeKnown(newType, receiver);
- instruction.block.addBefore(instruction.next, converted);
- receiver.replaceAllUsersDominatedBy(converted.next, converted);
- addDependentInstructionsToWorkList(converted);
+ TypeMask newType = compiler.world.allFunctions.receiverType(selector);
+ newType = newType.intersection(receiverType, compiler);
+ var next = instruction.next;
+ if (next is HTypeKnown && next.checkedInput == receiver) {
+ // We already have refined [receiver]. We still update the
+ // type of the [HTypeKnown] instruction because it may have
+ // been refined with a correct type at the time, but
+ // incorrect now.
+ if (next.instructionType != newType) {
+ next.knownType = next.instructionType = newType;
+ addDependentInstructionsToWorkList(next);
}
+ } else if (newType != receiverType) {
+ // Insert a refinement node after the call and update all
+ // users dominated by the call to use that node instead of
+ // [receiver].
+ HTypeKnown converted = new HTypeKnown(newType, receiver);
+ instruction.block.addBefore(instruction.next, converted);
+ receiver.replaceAllUsersDominatedBy(converted.next, converted);
+ addDependentInstructionsToWorkList(converted);
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
index 829012d..e36bec1 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
@@ -677,9 +677,11 @@
Range visitFieldGet(HFieldGet fieldGet) {
if (!fieldGet.isInteger(compiler)) return info.newUnboundRange();
- if (!fieldGet.receiver.isIndexable(compiler)) {
+ if (!fieldGet.receiver.isIndexablePrimitive(compiler)) {
return visitInstruction(fieldGet);
}
+ JavaScriptBackend backend = compiler.backend;
+ assert(fieldGet.element == backend.jsIndexableLength);
LengthValue value = info.newLengthValue(fieldGet);
// We know this range is above zero. To simplify the analysis, we
// put the zero value as the lower bound of this range. This
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index ac39ab2..d210715 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -572,6 +572,14 @@
bool needsNoSuchMethodHandling(Selector selector, Compiler compiler) {
throw new UnsupportedError("");
}
+
+ bool isInMask(TypeMask other, Compiler compiler) {
+ throw new UnsupportedError("");
+ }
+
+ bool containsMask(TypeMask other, Compiler compiler) {
+ throw new UnsupportedError("");
+ }
}
/**
diff --git a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
index c58baef..ec7ba94 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -82,6 +82,20 @@
}
}
+ bool isInMask(other, Compiler compiler) {
+ if (isEmpty) {
+ return isNullable ? other.isNullable : true;
+ }
+ if (other.isEmpty) return false;
+ if (isNullable && !other.isNullable) return false;
+ if (other is! FlatTypeMask) return other.containsMask(this, compiler);
+ return satisfies(other.base, compiler);
+ }
+
+ bool containsMask(TypeMask other, Compiler compiler) {
+ return other.isInMask(this, compiler);
+ }
+
bool containsOnlyInt(Compiler compiler) {
return base == compiler.intClass
|| base == compiler.backend.intImplementation;
@@ -122,7 +136,29 @@
bool satisfies(ClassElement cls, Compiler compiler) {
assert(cls.isDeclaration);
if (isEmpty) return false;
- return base == cls || isSubtypeOf(base, cls, compiler);
+ if (base == cls) return true;
+ if (isSubtypeOf(base, cls, compiler)) return true;
+
+ // Special case basic types so that, for example, String satisfies
+ // JSString.
+ // The general optimization is to realize there is only one class that
+ // implements [base] and [base] is not instantiated. We however do
+ // not track correctly the list of truly instantiated classes.
+ Backend backend = compiler.backend;
+ if (containsOnlyString(compiler)) {
+ return cls == compiler.stringClass || cls == backend.stringImplementation;
+ }
+ if (containsOnlyBool(compiler)) {
+ return cls == compiler.boolClass || cls == backend.boolImplementation;
+ }
+ if (containsOnlyInt(compiler)) {
+ return cls == compiler.intClass || cls == backend.intImplementation;
+ }
+ if (containsOnlyDouble(compiler)) {
+ return cls == compiler.doubleClass
+ || cls == compiler.backend.doubleImplementation;
+ }
+ return false;
}
/**
@@ -194,7 +230,7 @@
TypeMask unionSubclass(FlatTypeMask other, Compiler compiler) {
assert(isSubclassOf(other.base, base, compiler));
int combined;
- if (isExact && other.isExact) {
+ if ((isExact && other.isExact) || base == compiler.objectClass) {
// Since the other mask is a subclass of this mask, we need the
// resulting union to be a subclass too. If either one of the
// masks are nullable the result should be nullable too.
diff --git a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
index 8f4c05f..bb7b7a9 100644
--- a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
@@ -22,6 +22,14 @@
bool get isContainer => false;
bool get isForwarding => true;
+ bool isInMask(TypeMask other, Compiler compiler) {
+ return forwardTo.isInMask(other, compiler);
+ }
+
+ bool containsMask(TypeMask other, Compiler compiler) {
+ return forwardTo.containsMask(other, compiler);
+ }
+
bool containsOnlyInt(Compiler compiler) {
return forwardTo.containsOnlyInt(compiler);
}
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index 27e2df5..e99a8f4 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -63,6 +63,16 @@
bool containsOnly(ClassElement element);
/**
+ * Returns whether this type mask is a subtype of [other].
+ */
+ bool isInMask(TypeMask other, Compiler compiler);
+
+ /**
+ * Returns whether [other] is a subtype of this type mask.
+ */
+ bool containsMask(TypeMask other, Compiler compiler);
+
+ /**
* Returns whether this type mask is an instance of [cls].
*/
bool satisfies(ClassElement cls, Compiler compiler);
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index 1a47e3b..e754376 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -180,7 +180,7 @@
TypeMask get nullType {
if (nullTypeCache == null) {
// TODO(johnniwinther): Assert that the null type has been resolved.
- nullTypeCache = new TypeMask.empty();
+ nullTypeCache = const TypeMask.empty();
}
return nullTypeCache;
}
diff --git a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
index e6232cc..de7fc8f 100644
--- a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
@@ -197,6 +197,14 @@
bool get isContainer => false;
bool get isForwarding => false;
+ bool isInMask(TypeMask other, Compiler compiler) {
+ return disjointMasks.every((mask) => mask.isInMask(other, compiler));
+ }
+
+ bool containsMask(TypeMask other, Compiler compiler) {
+ return disjointMasks.any((mask) => mask.containsMask(other, compiler));
+ }
+
bool containsOnlyInt(Compiler compiler) {
return disjointMasks.every((mask) => mask.containsOnlyInt(compiler));
}
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 5c0c9da..73bbb9f 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -622,6 +622,7 @@
new Map<Selector, Map<TypeMask, TypedSelector>>();
factory TypedSelector(TypeMask mask, Selector selector) {
+ if (selector.mask == mask) return selector;
Selector untyped = selector.asUntyped;
Map<TypeMask, TypedSelector> map = canonicalizedValues.putIfAbsent(untyped,
() => new Map<TypeMask, TypedSelector>());
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index fe12176..052d223 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -819,6 +819,11 @@
"Error: '#{type}' must not occur more than once "
"in the implements clause.");
+ static const MessageKind MULTI_INHERITANCE = const MessageKind(
+ "Internal Error: Inheritance of the same class with different type "
+ "arguments is not supported: Both #{firstType} and #{secondType} are "
+ "supertypes of #{thisType}.");
+
static const MessageKind ILLEGAL_SUPER_SEND = const MessageKind(
"Error: '#{name}' cannot be called on super.");
@@ -974,6 +979,9 @@
"foo(void x) {} main() { foo(null); }",
]);
+ static const MessageKind NULL_NOT_ALLOWED = const MessageKind(
+ "Error: `null` can't be used here.");
+
static const MessageKind BEFORE_TOP_LEVEL = const MessageKind(
"Error: Part header must come before top-level definitions.");
diff --git a/sdk/lib/_internal/compiler/implementation/world.dart b/sdk/lib/_internal/compiler/implementation/world.dart
index 722688d..971ac69 100644
--- a/sdk/lib/_internal/compiler/implementation/world.dart
+++ b/sdk/lib/_internal/compiler/implementation/world.dart
@@ -181,6 +181,11 @@
return subtypes != null && subtypes.contains(test.declaration);
}
+ bool isSubclass(ClassElement superclass, ClassElement test) {
+ Set<ClassElement> subclasses = subclassesOf(superclass);
+ return subclasses != null && subclasses.contains(test.declaration);
+ }
+
void registerUsedElement(Element element) {
if (element.isInstanceMember() && !element.isAbstract(compiler)) {
allFunctions.add(element);
diff --git a/sdk/lib/_internal/lib/core_patch.dart b/sdk/lib/_internal/lib/core_patch.dart
index 8e5bec0..601149a 100644
--- a/sdk/lib/_internal/lib/core_patch.dart
+++ b/sdk/lib/_internal/lib/core_patch.dart
@@ -105,7 +105,7 @@
patch factory int.fromEnvironment(String name, {int defaultValue}) {
throw new UnsupportedError(
- 'int.fromEnvironement can only be used as a const constructor');
+ 'int.fromEnvironment can only be used as a const constructor');
}
}
@@ -227,14 +227,14 @@
patch factory String.fromEnvironment(String name, {String defaultValue}) {
throw new UnsupportedError(
- 'String.fromEnvironement can only be used as a const constructor');
+ 'String.fromEnvironment can only be used as a const constructor');
}
}
patch class bool {
- patch factory bool.fromEnvironment(String name, {bool defaultValue}) {
+ patch factory bool.fromEnvironment(String name, {bool defaultValue: false}) {
throw new UnsupportedError(
- 'bool.fromEnvironement can only be used as a const constructor');
+ 'bool.fromEnvironment can only be used as a const constructor');
}
}
diff --git a/sdk/lib/_internal/lib/interceptors.dart b/sdk/lib/_internal/lib/interceptors.dart
index c5e340e..23955bb 100644
--- a/sdk/lib/_internal/lib/interceptors.dart
+++ b/sdk/lib/_internal/lib/interceptors.dart
@@ -11,6 +11,7 @@
Null,
JSSyntaxRegExp,
Primitives,
+ checkInt,
checkNull,
checkNum,
checkString,
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index 96671cd..802563e 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -207,7 +207,7 @@
TypeMirror get upperBound {
if (_cachedUpperBound != null) return _cachedUpperBound;
return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation(
- JS('', 'init.metadata[#]', _typeVariable.bound));
+ owner, getMetadata(_typeVariable.bound));
}
}
@@ -502,8 +502,7 @@
if (constructorOrInterceptor == null) {
int index = JS('int|Null', 'init.functionAliases[#]', mangledName);
if (index != null) {
- mirror = new JsTypedefMirror(
- symbol, mangledName, JS('=Object', 'init.metadata[#]', index));
+ mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index));
JsCache.update(classMirrors, mangledName, mirror);
return mirror;
}
@@ -675,15 +674,6 @@
"Can't instantiate mixin application '${n(qualifiedName)}'");
}
- Future<InstanceMirror> newInstanceAsync(
- Symbol constructorName,
- List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return new Future<InstanceMirror>(
- () => this.newInstance(
- constructorName, positionalArguments, namedArguments));
- }
-
bool get isOriginalDeclaration => true;
ClassMirror get originalDeclaration => this;
@@ -697,20 +687,6 @@
}
abstract class JsObjectMirror implements ObjectMirror {
- Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
- return new Future<InstanceMirror>(() => this.setField(fieldName, value));
- }
-
- Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
- return new Future<InstanceMirror>(() => this.getField(fieldName));
- }
-
- Future<InstanceMirror> invokeAsync(Symbol memberName,
- List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return new Future<InstanceMirror>(
- () => this.invoke(memberName, positionalArguments, namedArguments));
- }
}
class JsInstanceMirror extends JsObjectMirror implements InstanceMirror {
@@ -722,14 +698,6 @@
ClassMirror get type => reflectType(reflectee.runtimeType);
- Future<InstanceMirror> invokeAsync(Symbol memberName,
- List<Object> positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return
- new Future<InstanceMirror>(
- () => invoke(memberName, positionalArguments, namedArguments));
- }
-
InstanceMirror invoke(Symbol memberName,
List positionalArguments,
[Map<Symbol,dynamic> namedArguments]) {
@@ -748,7 +716,7 @@
var defaultValueIndices =
JS('List|Null', '#[#].\$defaultValues', reflectee, mangledName);
var defaultValues =
- defaultValueIndices.map((int i) => JS('', 'init.metadata[#]', i))
+ defaultValueIndices.map((int i) => getMetadata(i))
.iterator;
var defaultArguments = new Map();
reflectiveName = mangledNames[mangledName];
@@ -882,30 +850,36 @@
* When instantiated this field will hold a string representing the list of
* type arguments for the class, i.e. what is inside the outermost angle
* brackets. Then, when get typeArguments is called the first time, the string
- * is parsed into the actual list of TypeMirrors, and the field is overridden
- * with this value.
+ * is parsed into the actual list of TypeMirrors, and stored in
+ * [_cachedTypeArguments]. Due to type substitution of, for instance,
+ * superclasses the mangled name of the class and hence this string is needed
+ * after [_cachedTypeArguments] has been computed.
*
* If an integer is encountered as a type argument, it represents the type
* variable at the corresponding entry in [emitter.globalMetadata].
*/
- var _typeArguments;
+ String _typeArguments;
+ UnmodifiableListView<TypeMirror> _cachedTypeArguments;
Map<Symbol, VariableMirror> _cachedVariables;
Map<Symbol, MethodMirror> _cachedGetters;
Map<Symbol, MethodMirror> _cachedSetters;
Map<Symbol, MethodMirror> _cachedMethodsMap;
List<JsMethodMirror> _cachedMethods;
+ ClassMirror _superclass;
+ List<ClassMirror> _cachedSuperinterfaces;
JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments)
- : _class = originalDeclaration,
+ : _class = originalDeclaration,
super(originalDeclaration.simpleName);
String get _prettyName => 'ClassMirror';
-
+ String get _mangledName => '${_class._mangledName}<$_typeArguments>';
+
List<TypeVariableMirror> get typeVariables => _class.typeVariables;
List<TypeMirror> get typeArguments {
- if (_typeArguments is! String) return _typeArguments;
+ if (_cachedTypeArguments != null) return _cachedTypeArguments;
List result = new List();
addTypeArgument(String typeArgument) {
@@ -913,7 +887,7 @@
if (parsedIndex == -1) {
result.add(reflectClassByMangledName(typeArgument.trim()));
} else {
- TypeVariable typeVariable = JS('', 'init.metadata[#]', parsedIndex);
+ TypeVariable typeVariable = getMetadata(parsedIndex);
TypeMirror owner = reflectClass(typeVariable.owner);
TypeVariableMirror typeMirror =
new JsTypeVariableMirror(typeVariable, owner);
@@ -950,7 +924,7 @@
}
addTypeArgument(currentTypeArgument);
}
- return _typeArguments = new UnmodifiableListView(result);
+ return _cachedTypeArguments = new UnmodifiableListView(result);
}
Map<Symbol, MethodMirror> get constructors => _class.constructors;
@@ -1004,20 +978,19 @@
namedArguments);
}
- Future<InstanceMirror> newInstanceAsync(
- Symbol constructorName,
- List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return _class.newInstanceAsync(constructorName,
- positionalArguments,
- namedArguments);
- }
-
JsLibraryMirror get owner => _class.owner;
List<InstanceMirror> get metadata => _class.metadata;
- ClassMirror get superclass => _class.superclass;
+ ClassMirror get superclass {
+ if (_superclass != null) return _superclass;
+
+ List<int> typeInformation =
+ JS('List|Null', 'init.typeInformation[#]', _class._mangledName);
+ assert(typeInformation != null);
+ var type = getMetadata(typeInformation[0]);
+ return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
+ }
InstanceMirror invoke(Symbol memberName,
List positionalArguments,
@@ -1029,20 +1002,13 @@
ClassMirror get originalDeclaration => _class;
- List<ClassMirror> get superinterfaces => _class.superinterfaces;
-
- Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
- return _class.getFieldAsync(fieldName);
+ List<ClassMirror> get superinterfaces {
+ if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
+ return _cachedSuperinterfaces = _class._getSuperinterfacesWithOwner(this);
}
bool get hasReflectedType => _class.hasReflectedType;
- Future<InstanceMirror> invokeAsync(Symbol memberName,
- List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return _class.invokeAsync(memberName, positionalArguments, namedArguments);
- }
-
bool get isPrivate => _class.isPrivate;
bool get isTopLevel => _class.isTopLevel;
@@ -1055,10 +1021,6 @@
Type get reflectedType => _class.reflectedType;
- Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
- return _class.setFieldAsync(fieldName, value);
- }
-
Symbol get simpleName => _class.simpleName;
}
@@ -1313,18 +1275,6 @@
return reflect(mirror._invoke(positionalArguments, namedArguments));
}
- Future<InstanceMirror> newInstanceAsync(
- Symbol constructorName,
- List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments != null && !namedArguments.isEmpty) {
- throw new UnsupportedError('Named arguments are not implemented.');
- }
- return new Future<InstanceMirror>(
- () => newInstance(
- constructorName, positionalArguments, namedArguments));
- }
-
JsLibraryMirror get owner {
if (_owner == null) {
if (_jsConstructorOrInterceptor is Interceptor) {
@@ -1357,19 +1307,28 @@
ClassMirror get superclass {
if (_superclass == null) {
- var superclassName = _fieldsDescriptor.split(';')[0];
- var mixins = superclassName.split('+');
- if (mixins.length > 1) {
- if (mixins.length != 2) {
- throw new RuntimeError('Strange mixin: $_fieldsDescriptor');
- }
- _superclass = reflectClassByMangledName(mixins[0]);
+ List<int> typeInformation =
+ JS('List|Null', 'init.typeInformation[#]', _mangledName);
+ if (typeInformation != null) {
+ var type = getMetadata(typeInformation[0]);
+ _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
} else {
- // Use _superclass == this to represent class with no superclass (Object).
- _superclass = (superclassName == '')
- ? this : reflectClassByMangledName(superclassName);
+ var superclassName = _fieldsDescriptor.split(';')[0];
+ // TODO(zarah): Remove special handing of mixins.
+ var mixins = superclassName.split('+');
+ if (mixins.length > 1) {
+ if (mixins.length != 2) {
+ throw new RuntimeError('Strange mixin: $_fieldsDescriptor');
+ }
+ _superclass = reflectClassByMangledName(mixins[0]);
+ } else {
+ // Use _superclass == this to represent class with no superclass
+ // (Object).
+ _superclass = (superclassName == '')
+ ? this : reflectClassByMangledName(superclassName);
+ }
+ }
}
- }
return _superclass == this ? null : _superclass;
}
@@ -1398,19 +1357,26 @@
ClassMirror get originalDeclaration => this;
+ List<ClassMirror> _getSuperinterfacesWithOwner(DeclarationMirror owner) {
+ List<int> typeInformation =
+ JS('List|Null', 'init.typeInformation[#]', _mangledName);
+ List<ClassMirror> result = const <ClassMirror>[];
+ if (typeInformation != null) {
+ ClassMirror lookupType(int i) {
+ var type = getMetadata(i);
+ return typeMirrorFromRuntimeTypeRepresentation(owner, type);
+ }
+
+ //We skip the first since it is the supertype.
+ result = typeInformation.skip(1).map(lookupType).toList();
+ }
+
+ return new UnmodifiableListView<ClassMirror>(result);
+ }
+
List<ClassMirror> get superinterfaces {
if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
- List<int> interfaces = JS('List|Null', 'init.interfaces[#]', _mangledName);
- var result = const [];
- if (interfaces != null) {
- ClassMirror lookupType(int i) {
- var type = JS('=Object', 'init.metadata[#]', i);
- return typeMirrorFromRuntimeTypeRepresentation(type);
- }
- result = interfaces.map(lookupType).toList();
- }
- return _cachedSuperinterfaces =
- new UnmodifiableListView<ClassMirror>(result);
+ return _cachedSuperinterfaces = _getSuperinterfacesWithOwner(this);
}
List<TypeVariableMirror> get typeVariables {
@@ -1420,7 +1386,7 @@
JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor);
if (typeVariables == null) return result;
for (int i = 0; i < typeVariables.length; i++) {
- TypeVariable typeVariable = JS('', 'init.metadata[#]', typeVariables[i]);
+ TypeVariable typeVariable = getMetadata(typeVariables[i]);
result.add(new JsTypeVariableMirror(typeVariable, this));
}
return _cachedTypeVariables = new UnmodifiableListView(result);
@@ -1583,18 +1549,13 @@
Function.apply(reflectee, positionalArguments, namedArguments));
}
- Future<InstanceMirror> applyAsync(List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return new Future<InstanceMirror>(
- () => apply(positionalArguments, namedArguments));
- }
-
String toString() => "ClosureMirror on '${Error.safeToString(reflectee)}'";
// TODO(ahe): Implement these.
String get source => throw new UnimplementedError();
- Future<InstanceMirror> findInContext(Symbol name)
- => throw new UnimplementedError();
+ InstanceMirror findInContext(Symbol name) {
+ throw new UnsupportedError("ClosureMirror.findInContext not yet supported");
+ }
}
class JsMethodMirror extends JsDeclarationMirror implements MethodMirror {
@@ -1663,7 +1624,7 @@
TypeMirror get returnType {
metadata; // Compute _returnType as a side-effect of extracting metadata.
- return computeTypeMirror(owner, _returnType);
+ return typeMirrorFromRuntimeTypeRepresentation(owner, _returnType);
}
List<InstanceMirror> get metadata {
@@ -1762,7 +1723,7 @@
String get _prettyName => 'ParameterMirror';
TypeMirror get type {
- return computeTypeMirror(owner, _type);
+ return typeMirrorFromRuntimeTypeRepresentation(owner, _type);
}
// Only true for static fields, never for a parameter.
@@ -1823,13 +1784,14 @@
bool get _hasNamedArguments => JS('bool', '"named" in #', _typeData);
get _namedArguments => JS('=Object', '#.named', _typeData);
+ bool get isOriginalDeclaration => true;
TypeMirror get returnType {
if (_cachedReturnType != null) return _cachedReturnType;
if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType;
if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType;
return _cachedReturnType =
- typeMirrorFromRuntimeTypeRepresentation(_returnType);
+ typeMirrorFromRuntimeTypeRepresentation(this, _returnType);
}
List<ParameterMirror> get parameters {
@@ -1902,18 +1864,20 @@
}
}
-TypeMirror typeMirrorFromRuntimeTypeRepresentation(type) {
- if (type == null) return JsMirrorSystem._dynamicType;
- String representation = runtimeTypeToString(type);
- if (representation == null) return reflectClass(Function);
- return reflectType(createRuntimeType(representation));
+int findTypeVariableIndex(List<TypeVariableMirror> typeVariables, String name) {
+ for (int i = 0; i < typeVariables.length; i++) {
+ if (typeVariables[i].simpleName == s(name)) {
+ return i;
+ }
+ }
+ throw new ArgumentError('Type variable not present in list.');
}
-TypeMirror computeTypeMirror(DeclarationMirror owner, var type) {
- if (type is! int) {
- return typeMirrorFromRuntimeTypeRepresentation(type);
- }
-
+getMetadata(int index) => JS('', 'init.metadata[#]', index);
+
+TypeMirror typeMirrorFromRuntimeTypeRepresentation(
+ DeclarationMirror owner,
+ var /*int|List|JsFunction*/ type) {
ClassMirror ownerClass;
DeclarationMirror context = owner;
while(context != null) {
@@ -1923,19 +1887,42 @@
}
context = context.owner;
}
-
- TypeVariable typeVariable = JS('', 'init.metadata[#]', type);
- Symbol name = new Symbol(typeVariable.name);
- List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
- for (int i = 0; i < typeVariables.length; i++) {
- if (typeVariables[i].simpleName == name) {
- if (ownerClass.isOriginalDeclaration) {
- return typeVariables[i];
- } else {
- return ownerClass.typeArguments[i];
- }
+
+ String representation;
+ if (type == null){
+ return JsMirrorSystem._dynamicType;
+ } else if (ownerClass == null) {
+ representation = runtimeTypeToString(type);
+ } else if (ownerClass.isOriginalDeclaration) {
+ if (type is int) {
+ // [type] represents a type variable so in the context of an original
+ // declaration the corresponding type variable should be returned.
+ TypeVariable typeVariable = getMetadata(type);
+ List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
+ int index = findTypeVariableIndex(typeVariables, typeVariable.name);
+ return typeVariables[index];
+ } else {
+ // Nested type variables will be retrieved lazily (the integer
+ // representation is kept in the string) so they are not processed here.
+ representation = runtimeTypeToString(type);
}
+ } else {
+ String substituteTypeVariable(int index) {
+ TypeVariable typeVariable = getMetadata(index);
+ int variableIndex =
+ findTypeVariableIndex(ownerClass.typeVariables, typeVariable.name);
+ var typeArgument = ownerClass.typeArguments[variableIndex];
+ assert(typeArgument is JsClassMirror ||
+ typeArgument is JsTypeBoundClassMirror);
+ return typeArgument._mangledName;
+ }
+ representation =
+ runtimeTypeToString(type, onTypeVariable: substituteTypeVariable);
}
+ if (representation != null) {
+ return reflectType(createRuntimeType(representation));
+ }
+ return reflectClass(Function);
}
Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
@@ -1955,7 +1942,7 @@
index++;
int endQuote = source.indexOf('"', index);
return source.substring(index, endQuote).split(',').map(int.parse).map(
- (int i) => JS('', 'init.metadata[#]', i)).toList();
+ (int i) => getMetadata(i)).toList();
}
List<JsVariableMirror> parseCompactFieldSpecification(
diff --git a/sdk/lib/_internal/lib/js_rti.dart b/sdk/lib/_internal/lib/js_rti.dart
index 3670841..67dd441 100644
--- a/sdk/lib/_internal/lib/js_rti.dart
+++ b/sdk/lib/_internal/lib/js_rti.dart
@@ -134,10 +134,11 @@
* of type 4, the JavaScript array, where the first element represents the class
* and the remaining elements represent the type arguments.
*/
-String getRuntimeTypeAsString(var runtimeType) {
+String getRuntimeTypeAsString(var runtimeType, {String onTypeVariable(int i)}) {
assert(isJsArray(runtimeType));
String className = getConstructorName(getIndex(runtimeType, 0));
- return '$className${joinArguments(runtimeType, 1)}';
+ return '$className'
+ '${joinArguments(runtimeType, 1, onTypeVariable: onTypeVariable)}';
}
/**
@@ -149,17 +150,21 @@
/**
* Returns a human-readable representation of the type representation [type].
*/
-String runtimeTypeToString(var type) {
+String runtimeTypeToString(var type , {String onTypeVariable(int i)}) {
if (isNull(type)) {
return 'dynamic';
} else if (isJsArray(type)) {
// A list representing a type with arguments.
- return getRuntimeTypeAsString(type);
+ return getRuntimeTypeAsString(type, onTypeVariable: onTypeVariable);
} else if (isJsFunction(type)) {
// A reference to the constructor.
return getConstructorName(type);
} else if (type is int) {
- return type.toString();
+ if (onTypeVariable == null) {
+ return type.toString();
+ } else {
+ return onTypeVariable(type);
+ }
} else {
return null;
}
@@ -170,7 +175,8 @@
* type representations in the JavaScript array [types] starting at index
* [startIndex].
*/
-String joinArguments(var types, int startIndex) {
+String joinArguments(var types, int startIndex,
+ {String onTypeVariable(int i)}) {
if (isNull(types)) return '';
assert(isJsArray(types));
bool firstArgument = true;
@@ -186,7 +192,7 @@
if (argument != null) {
allDynamic = false;
}
- buffer.write(runtimeTypeToString(argument));
+ buffer.write(runtimeTypeToString(argument, onTypeVariable: onTypeVariable));
}
return allDynamic ? '' : '<$buffer>';
}
diff --git a/sdk/lib/_internal/lib/js_string.dart b/sdk/lib/_internal/lib/js_string.dart
index 8a8ac16..0dd8066 100644
--- a/sdk/lib/_internal/lib/js_string.dart
+++ b/sdk/lib/_internal/lib/js_string.dart
@@ -14,7 +14,7 @@
const JSString();
int codeUnitAt(int index) {
- if (index is !num) throw new ArgumentError(index);
+ if (index is !int) throw new ArgumentError(index);
if (index < 0) throw new RangeError.value(index);
if (index >= length) throw new RangeError.value(index);
return JS('int', r'#.charCodeAt(#)', this, index);
@@ -84,6 +84,7 @@
}
bool startsWith(Pattern pattern, [int index = 0]) {
+ checkInt(index);
if (index < 0 || index > this.length) {
throw new RangeError.range(index, 0, this.length);
}
@@ -92,16 +93,15 @@
int otherLength = other.length;
int endIndex = index + otherLength;
if (endIndex > length) return false;
- return JS('bool', r'# == #', other,
- JS('String', r'#.substring(#, #)', this, index, endIndex));
+ return other == JS('String', r'#.substring(#, #)', this, index, endIndex);
}
return pattern.matchAsPrefix(this, index) != null;
}
String substring(int startIndex, [int endIndex]) {
- checkNum(startIndex);
+ checkInt(startIndex);
if (endIndex == null) endIndex = length;
- checkNum(endIndex);
+ checkInt(endIndex);
if (startIndex < 0 ) throw new RangeError.value(startIndex);
if (startIndex > endIndex) throw new RangeError.value(startIndex);
if (endIndex > length) throw new RangeError.value(endIndex);
diff --git a/sdk/lib/_internal/lib/native_helper.dart b/sdk/lib/_internal/lib/native_helper.dart
index 03b0ef5..799960e 100644
--- a/sdk/lib/_internal/lib/native_helper.dart
+++ b/sdk/lib/_internal/lib/native_helper.dart
@@ -46,7 +46,7 @@
/**
* Returns a String tag identifying the type of the native object, or `null`.
* The tag is not the name of the type, but usually the name of the JavaScript
- * constructor function.
+ * constructor function. Initialized by [initHooks].
*/
Function getTagFunction;
@@ -54,10 +54,18 @@
* If a lookup via [getTagFunction] on an object [object] that has [tag] fails,
* this function is called to provide an alternate tag. This allows us to fail
* gracefully if we can make a good guess, for example, when browsers add novel
- * kinds of HTMLElement that we have never heard of.
+ * kinds of HTMLElement that we have never heard of. Initialized by
+ * [initHooks].
*/
Function alternateTagFunction;
+/**
+ * Returns the prototype for the JavaScript constructor named by an input tag.
+ * Returns `null` if there is no such constructor, or if pre-patching of the
+ * constructor is to be avoided. Initialized by [initHooks].
+ */
+Function prototypeForTagFunction;
+
String toStringForNativeObject(var obj) {
// TODO(sra): Is this code dead?
@@ -303,15 +311,12 @@
var context = JS('=Object', 'window');
for (int i = 0; i < tags.length; i++) {
var tag = tags[i];
- if (JS('bool', 'typeof (#[#]) == "function"', context, tag)) {
- var constructor = JS('', '#[#]', context, tag);
- var proto = JS('', '#.prototype', constructor);
- if (proto != null) { // E.g. window.mozRTCIceCandidate.prototype
- var interceptorClass = JS('', '#[#]', map, tag);
- var record = makeDefaultDispatchRecord(tag, interceptorClass, proto);
- if (record != null) {
- setDispatchProperty(proto, record);
- }
+ var proto = prototypeForTagFunction(tag);
+ if (proto != null) {
+ var interceptorClass = JS('', '#[#]', map, tag);
+ var record = makeDefaultDispatchRecord(tag, interceptorClass, proto);
+ if (record != null) {
+ setDispatchProperty(proto, record);
}
}
}
@@ -347,12 +352,15 @@
*
* { getTag: function(obj) {...},
* getUnknownTag: function(obj, tag) {...},
+ * prototypeForTag: function(tag) {...},
* discriminator: function(tag) {...},
* }
*
* * getTag(obj) returns the dispatch tag, or `null`.
* * getUnknownTag(obj, tag) returns a tag when [getTag] fails.
- * * discriminator returns a function TBD.
+ * * prototypeForTag(tag) returns the prototype of the constructor for tag,
+ * or `null` if not available or prepatching is undesirable.
+ * * discriminator(tag) returns a function TBD.
*
* The web site can adapt a dart2js application by loading code ahead of the
* dart2js application that defines hook transformers to be after the built in
@@ -408,10 +416,13 @@
var getTag = JS('', '#.getTag', hooks);
var getUnknownTag = JS('', '#.getUnknownTag', hooks);
+ var prototypeForTag = JS('', '#.prototypeForTag', hooks);
getTagFunction = (o) => JS('String|Null', '#(#)', getTag, o);
alternateTagFunction =
(o, String tag) => JS('String|Null', '#(#, #)', getUnknownTag, o, tag);
+ prototypeForTagFunction =
+ (String tag) => JS('', '#(#)', prototypeForTag, tag);
}
applyHooksTransformer(transformer, hooks) {
@@ -419,7 +430,6 @@
return JS('', '# || #', newHooks, hooks);
}
-
// JavaScript code fragments.
//
// This is a temporary place for the JavaScript code.
@@ -445,6 +455,13 @@
if (object instanceof HTMLElement) return "HTMLElement";
return getUnknownTag(object, tag);
}
+ function prototypeForTag(tag) {
+ if (typeof window == "undefined") return null;
+ if (typeof window[tag] == "undefined") return null;
+ var constructor = window[tag];
+ if (typeof constructor != "function") return null;
+ return constructor.prototype;
+ }
function discriminator(tag) { return null; }
var isBrowser = typeof navigator == "object";
@@ -452,6 +469,7 @@
return {
getTag: typeNameInChrome,
getUnknownTag: isBrowser ? getUnknownTagGenericBrowser : getUnknownTag,
+ prototypeForTag: prototypeForTag,
discriminator: discriminator };
}''');
@@ -544,7 +562,15 @@
return tag;
}
+ function prototypeForTagIE(tag) {
+ if (tag == "Document") return null; // Do not pre-patch Document.
+ var constructor = window[tag];
+ if (constructor == null) return null;
+ return constructor.prototype;
+ }
+
hooks.getTag = getTagIE;
+ hooks.prototypeForTag = prototypeForTagIE;
}''');
diff --git a/sdk/lib/_internal/pub/lib/src/barback.dart b/sdk/lib/_internal/pub/lib/src/barback.dart
index 84a069a..7e317f63 100644
--- a/sdk/lib/_internal/pub/lib/src/barback.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback.dart
@@ -23,11 +23,10 @@
/// It's possible that the library identified by [this] defines multiple
/// transformers. If so, [configuration] will be passed to all of them.
class TransformerId {
- /// The package containing the library that this transformer identifies.
+ /// The package containing the library where the transformer is defined.
final String package;
- /// The `/`-separated path identifying the library that contains this
- /// transformer.
+ /// The `/`-separated path to the library that contains this transformer.
///
/// This is relative to the `lib/` directory in [package], and doesn't end in
/// `.dart`.
@@ -108,7 +107,8 @@
/// monitor the app and its dependencies for any updates. Otherwise the state of
/// the app when the server is started will be maintained.
Future<BarbackServer> createServer(String host, int port, PackageGraph graph,
- {Iterable<Transformer> builtInTransformers, bool watchForUpdates: true}) {
+ BarbackMode mode, {Iterable<Transformer> builtInTransformers,
+ bool watchForUpdates: true}) {
var provider = new PubPackageProvider(graph);
var barback = new Barback(provider);
@@ -140,7 +140,7 @@
})
];
- loadAllTransformers(server, graph, builtInTransformers).then((_) {
+ loadAllTransformers(server, graph, mode, builtInTransformers).then((_) {
if (!completer.isCompleted) completer.complete(server);
}).catchError((error, stackTrace) {
if (!completer.isCompleted) completer.completeError(error, stackTrace);
@@ -302,4 +302,4 @@
log.message("$prefix\n$message");
break;
}
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
index ff9f1ac..ed36c55 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
@@ -23,7 +23,7 @@
/// Any [builtInTransformers] that are provided will automatically be added to
/// the end of every package's cascade.
Future loadAllTransformers(BarbackServer server, PackageGraph graph,
- [Iterable<Transformer> builtInTransformers]) {
+ BarbackMode mode, Iterable<Transformer> builtInTransformers) {
// In order to determine in what order we should load transformers, we need to
// know which transformers depend on which others. This is different than
// normal package dependencies. Let's begin with some terminology:
@@ -62,7 +62,7 @@
var orderingDeps = _computeOrderingDeps(graph);
var packageTransformers = _computePackageTransformers(graph);
- var loader = new _TransformerLoader(server, graph);
+ var loader = new _TransformerLoader(server, mode, graph);
// The packages on which no packages have ordering dependencies -- that is,
// the packages that don't need to be loaded before any other packages. These
@@ -206,6 +206,9 @@
class _TransformerLoader {
final BarbackServer _server;
+ /// The mode that pub is running barback in.
+ final BarbackMode _mode;
+
/// The loaded transformers defined in the library identified by each
/// transformer id.
final _transformers = new Map<TransformerId, Set<Transformer>>();
@@ -215,7 +218,7 @@
/// Used for error reporting.
final _transformerUsers = new Map<Pair<String, String>, Set<String>>();
- _TransformerLoader(this._server, PackageGraph graph) {
+ _TransformerLoader(this._server, this._mode, PackageGraph graph) {
for (var package in graph.packages.values) {
for (var id in unionAll(package.pubspec.transformers)) {
_transformerUsers.putIfAbsent(
@@ -235,7 +238,7 @@
// TODO(nweiz): load multiple instances of the same transformer from the
// same isolate rather than spinning up a separate isolate for each one.
- return loadTransformers(_server, id).then((transformers) {
+ return loadTransformers(_server, _mode, id).then((transformers) {
if (!transformers.isEmpty) {
_transformers[id] = transformers;
return;
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
index 2552b09..38938be 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
@@ -39,7 +39,8 @@
_respond(wrappedMessage, (message) {
var library = Uri.parse(message['library']);
var configuration = JSON.decode(message['configuration']);
- return initialize(library, configuration).
+ var mode = new BarbackMode(message['mode']);
+ return initialize(library, configuration, mode).
map(_serializeTransformerOrGroup).toList();
});
});
@@ -48,9 +49,8 @@
/// Loads all the transformers and groups defined in [uri].
///
/// Loads the library, finds any Transformer or TransformerGroup subclasses in
-/// it, instantiates them (with [configuration] if it's non-null), and returns
-/// them.
-Iterable initialize(Uri uri, Map configuration) {
+/// it, instantiates them with [configuration] and [mode], and returns them.
+Iterable initialize(Uri uri, Map configuration, BarbackMode mode) {
var mirrors = currentMirrorSystem();
var transformerClass = reflectClass(Transformer);
var groupClass = reflectClass(TransformerGroup);
@@ -77,10 +77,8 @@
// to an empty map.
if (configuration == null) configuration = {};
- // TODO(nweiz): if the constructor accepts named parameters, automatically
- // destructure the configuration map.
- return classMirror.newInstance(const Symbol('asPlugin'), [configuration])
- .reflectee;
+ return classMirror.newInstance(const Symbol('asPlugin'),
+ [new BarbackSettings(configuration, mode)]).reflectee;
}).where((classMirror) => classMirror != null);
}
@@ -444,7 +442,8 @@
/// [id].
///
/// [server] is used to serve any Dart files needed to load the transformers.
-Future<Set> loadTransformers(BarbackServer server, TransformerId id) {
+Future<Set> loadTransformers(BarbackServer server, BarbackMode mode,
+ TransformerId id) {
return id.getAssetId(server.barback).then((assetId) {
var path = assetId.path.replaceFirst('lib/', '');
// TODO(nweiz): load from a "package:" URI when issue 12474 is fixed.
@@ -460,6 +459,7 @@
.then((sendPort) {
return _call(sendPort, {
'library': uri,
+ 'mode': mode.name,
// TODO(nweiz): support non-JSON-encodable configuration maps.
'configuration': JSON.encode(id.configuration)
}).then((transformers) {
@@ -552,7 +552,7 @@
if (message['type'] == 'addOutput') {
transform.addOutput(_deserializeAsset(message['output']));
- return;
+ return null;
}
assert(message['type'] == 'log');
diff --git a/sdk/lib/_internal/pub/lib/src/command/build.dart b/sdk/lib/_internal/pub/lib/src/command/build.dart
index 93dee74..12dccf0 100644
--- a/sdk/lib/_internal/pub/lib/src/command/build.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/build.dart
@@ -58,7 +58,8 @@
// Since this server will only be hit by the transformer loader and isn't
// user-facing, just use an IPv4 address to avoid a weird bug on the
// OS X buildbots.
- return barback.createServer("127.0.0.1", 0, graph,
+ // TODO(rnystrom): Allow specifying mode.
+ return barback.createServer("127.0.0.1", 0, graph, BarbackMode.RELEASE,
builtInTransformers: [dart2jsTransformer],
watchForUpdates: false);
}).then((server) {
diff --git a/sdk/lib/_internal/pub/lib/src/command/serve.dart b/sdk/lib/_internal/pub/lib/src/command/serve.dart
index 0d7adfc..d3df35a 100644
--- a/sdk/lib/_internal/pub/lib/src/command/serve.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/serve.dart
@@ -6,6 +6,8 @@
import 'dart:async';
+import 'package:barback/barback.dart';
+
import '../barback/dart_forwarding_transformer.dart';
import '../barback/dart2js_transformer.dart';
import '../barback/pub_package_provider.dart';
@@ -75,7 +77,8 @@
];
}
- return barback.createServer(hostname, port, graph,
+ // TODO(rnystrom): Allow specifying other modes.
+ return barback.createServer(hostname, port, graph, BarbackMode.DEBUG,
builtInTransformers: builtInTransformers);
}).then((server) {
/// This completer is used to keep pub running (by not completing) and
diff --git a/sdk/lib/_internal/pub/test/serve/utils.dart b/sdk/lib/_internal/pub/test/serve/utils.dart
index 1013aec..eb412a7 100644
--- a/sdk/lib/_internal/pub/test/serve/utils.dart
+++ b/sdk/lib/_internal/pub/test/serve/utils.dart
@@ -187,7 +187,7 @@
void waitForBuildSuccess() {
nextLine() {
return _pubServer.nextLine().then((line) {
- if (line.contains("successfully")) return;
+ if (line.contains("successfully")) return null;
// This line wasn't it, so ignore it and keep trying.
return nextLine();
diff --git a/sdk/lib/_internal/pub/test/transformer/configuration/configuration_defaults_to_empty_map_test.dart b/sdk/lib/_internal/pub/test/transformer/configuration/configuration_defaults_to_empty_map_test.dart
index e842245..e2f0511 100644
--- a/sdk/lib/_internal/pub/test/transformer/configuration/configuration_defaults_to_empty_map_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/configuration/configuration_defaults_to_empty_map_test.dart
@@ -17,16 +17,17 @@
import 'package:barback/barback.dart';
class ConfigTransformer extends Transformer {
- final Map configuration;
+ final BarbackSettings settings;
- ConfigTransformer.asPlugin(this.configuration);
+ ConfigTransformer.asPlugin(this.settings);
String get allowedExtensions => '.txt';
Future apply(Transform transform) {
return transform.primaryInput.readAsString().then((contents) {
var id = transform.primaryInput.id.changeExtension(".json");
- transform.addOutput(new Asset.fromString(id, JSON.encode(configuration)));
+ transform.addOutput(
+ new Asset.fromString(id, JSON.encode(settings.configuration)));
});
}
}
diff --git a/sdk/lib/_internal/pub/test/transformer/configuration/passes_configuration_to_a_transformer_test.dart b/sdk/lib/_internal/pub/test/transformer/configuration/passes_configuration_to_a_transformer_test.dart
index 321dc3d..1a040b6 100644
--- a/sdk/lib/_internal/pub/test/transformer/configuration/passes_configuration_to_a_transformer_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/configuration/passes_configuration_to_a_transformer_test.dart
@@ -17,16 +17,17 @@
import 'package:barback/barback.dart';
class ConfigTransformer extends Transformer {
- final Map configuration;
+ final BarbackSettings settings;
- ConfigTransformer.asPlugin(this.configuration);
+ ConfigTransformer.asPlugin(this.settings);
String get allowedExtensions => '.txt';
Future apply(Transform transform) {
return transform.primaryInput.readAsString().then((contents) {
var id = transform.primaryInput.id.changeExtension(".json");
- transform.addOutput(new Asset.fromString(id, JSON.encode(configuration)));
+ transform.addOutput(
+ new Asset.fromString(id, JSON.encode(settings.configuration)));
});
}
}
diff --git a/sdk/lib/_internal/pub/test/transformer/configuration/with_configuration_only_instantiates_configurable_transformers_test.dart b/sdk/lib/_internal/pub/test/transformer/configuration/with_configuration_only_instantiates_configurable_transformers_test.dart
index 36e7d47..3f0a195 100644
--- a/sdk/lib/_internal/pub/test/transformer/configuration/with_configuration_only_instantiates_configurable_transformers_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/configuration/with_configuration_only_instantiates_configurable_transformers_test.dart
@@ -17,16 +17,17 @@
import 'package:barback/barback.dart';
class ConfigTransformer extends Transformer {
- final Map configuration;
+ final BarbackSettings settings;
- ConfigTransformer.asPlugin(this.configuration);
+ ConfigTransformer.asPlugin(this.settings);
String get allowedExtensions => '.txt';
Future apply(Transform transform) {
return transform.primaryInput.readAsString().then((contents) {
var id = transform.primaryInput.id.changeExtension(".json");
- transform.addOutput(new Asset.fromString(id, JSON.encode(configuration)));
+ transform.addOutput(
+ new Asset.fromString(id, JSON.encode(settings.configuration)));
});
}
}
@@ -71,4 +72,4 @@
requestShould404("foo.out");
endPubServe();
});
-}
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
index 9bf0185..350a58c 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
@@ -32,4 +32,4 @@
'accept configuration were defined in ')));
pub.shouldExit(1);
});
-}
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_debug_in_serve_test.dart b/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_debug_in_serve_test.dart
new file mode 100644
index 0000000..f45b8da
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_debug_in_serve_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS d.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 pub_tests;
+
+import 'dart:convert';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import '../serve/utils.dart';
+
+final transformer = """
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:barback/barback.dart';
+
+class ModeTransformer extends Transformer {
+ final BarbackSettings settings;
+
+ ModeTransformer.asPlugin(this.settings);
+
+ String get allowedExtensions => '.txt';
+
+ Future apply(Transform transform) {
+ return transform.primaryInput.readAsString().then((contents) {
+ transform.addOutput(
+ new Asset.fromString(transform.primaryInput.id, settings.mode.name));
+ });
+ }
+}
+""";
+
+main() {
+ initConfig();
+ integration("mode defaults to 'debug' in pub serve", () {
+ d.dir(appPath, [
+ d.pubspec({
+ "name": "myapp",
+ "transformers": ["myapp/src/transformer"]
+ }),
+ d.dir("lib", [d.dir("src", [
+ d.file("transformer.dart", transformer)
+ ])]),
+ d.dir("web", [
+ d.file("foo.txt", "foo")
+ ])
+ ]).create();
+
+ createLockFile('myapp', pkg: ['barback']);
+
+ var server = startPubServe();
+ requestShouldSucceed("foo.txt", "debug");
+ endPubServe();
+ });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_release_in_build_test.dart b/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_release_in_build_test.dart
new file mode 100644
index 0000000..5109c82
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_release_in_build_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS d.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 pub_tests;
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+
+final transformer = """
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+
+class ModeTransformer extends Transformer {
+ final BarbackSettings settings;
+
+ ModeTransformer.asPlugin(this.settings);
+
+ String get allowedExtensions => '.txt';
+
+ Future apply(Transform transform) {
+ return transform.primaryInput.readAsString().then((contents) {
+ transform.addOutput(
+ new Asset.fromString(transform.primaryInput.id, settings.mode.name));
+ });
+ }
+}
+""";
+
+main() {
+ initConfig();
+ integration("mode defaults to 'release' in pub build", () {
+ d.dir(appPath, [
+ d.pubspec({
+ "name": "myapp",
+ "transformers": ["myapp/src/transformer"]
+ }),
+ d.dir("lib", [d.dir("src", [
+ d.file("transformer.dart", transformer)
+ ])]),
+ d.dir("web", [
+ d.file("foo.txt", "foo")
+ ])
+ ]).create();
+
+ createLockFile('myapp', pkg: ['barback']);
+
+ schedulePub(args: ["build"],
+ output: new RegExp(r"Built 1 file!"),
+ exitCode: 0);
+
+ d.dir(appPath, [
+ d.dir('build', [
+ d.file('foo.txt', 'release')
+ ])
+ ]).validate();
+ });
+}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index d0f39fb..e299eb0 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -67,8 +67,8 @@
controller.add(value);
controller.close();
},
- onError: (error) {
- controller.addError(error);
+ onError: (error, stackTrace) {
+ controller.addError(error, stackTrace);
controller.close();
});
return controller.stream;
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index d86a993..685e682 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -656,7 +656,7 @@
_StreamSinkWrapper(this._target);
void add(T data) { _target.add(data); }
void addError(Object error, [StackTrace stackTrace]) {
- _target.addError(error);
+ _target.addError(error, stackTrace);
}
Future close() => _target.close();
Future addStream(Stream<T> source) => _target.addStream(source);
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 75f232e..efac7ac 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -86,7 +86,7 @@
*
* The default [reviver] (when not provided) is the identity function.
*/
- Object decode(String source, {reviver(var key, var value)}) {
+ dynamic decode(String source, {reviver(var key, var value)}) {
if (reviver == null) return decoder.convert(source);
return new JsonDecoder(reviver).convert(source);
}
@@ -102,7 +102,7 @@
* If [toEncodable] is omitted, it defaults to calling `.toJson()` on the
* unencodable object.
*/
- Object encode(Object value, {toEncodable(var object)}) {
+ String encode(Object value, {toEncodable(var object)}) {
if (toEncodable == null) return encoder.convert(value);
return new JsonEncoder(toEncodable).convert(value);
}
@@ -117,7 +117,7 @@
final _Reviver _reviver;
_ReviverJsonCodec(this._reviver);
- Object decode(String source, {reviver(var key, var value)}) {
+ dynamic decode(String source, {reviver(var key, var value)}) {
if (reviver == null) reviver = _reviver;
return new JsonDecoder(reviver).convert(source);
}
@@ -256,7 +256,7 @@
*
* Throws [FormatException] if the input is not valid JSON text.
*/
- Object convert(String input) => _parseJson(input, _reviver);
+ dynamic convert(String input) => _parseJson(input, _reviver);
/**
* Starts a conversion from a chunked JSON string to its corresponding
diff --git a/sdk/lib/core/annotations.dart b/sdk/lib/core/annotations.dart
index f7c412c..68ba572 100644
--- a/sdk/lib/core/annotations.dart
+++ b/sdk/lib/core/annotations.dart
@@ -79,7 +79,7 @@
/**
* Marks a feature as [Deprecated] until the next release.
*/
-const deprecated = const Deprecated("next release");
+const Deprecated deprecated = const Deprecated("next release");
/*
* The annotation `@override` marks an instance member as overriding a
@@ -106,7 +106,7 @@
* For example, the annotation is intentionally not used in the Dart platform
* libraries, since they only depend on themselves.
*/
-const override = const _Override();
+const Object override = const _Override();
class _Proxy {
const _Proxy();
@@ -130,4 +130,4 @@
* The intent of the `@proxy` notation is to avoid irrelevant warnings when
* a class implements its interface through `noSuchMethod`.
*/
-const proxy = const _Proxy();
+const Object proxy = const _Proxy();
diff --git a/sdk/lib/core/bool.dart b/sdk/lib/core/bool.dart
index c4348b7..8150219 100644
--- a/sdk/lib/core/bool.dart
+++ b/sdk/lib/core/bool.dart
@@ -13,10 +13,25 @@
*/
class bool {
/**
- * Returns the boolean for the given environment variable [name] or
- * [defaultValue] if [name] is not present.
+ * Returns the boolean value of the environment declaration [name].
+ *
+ * The boolean value of the declaration is `true` if the declared value is
+ * the string `"true"`, and `false` if the value is `"false"`.
+ *
+ * In all other cases, including when there is no declaration for `name`,
+ * the result is the [defaultValue].
+ *
+ * Example:
+ *
+ * const loggingFlag = const bool.fromEnvironment("logging");
+ *
+ * If you want to use a different truth-string, you can use the
+ * [String.fromEnvironment] constructor directly:
+ *
+ * const isLoggingOn = (const String.fromEnvironment("logging") == "on");
*/
- external const factory bool.fromEnvironment(String name, {bool defaultValue});
+ external const factory bool.fromEnvironment(String name,
+ {bool defaultValue: false});
/**
* Returns [:"true":] if the receiver is [:true:], or [:"false":] if the
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 1c17a31..c06a3ee 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -19,6 +19,20 @@
*/
abstract class int extends num {
/**
+ * Returns the integer value of the given environment declaration [name].
+ *
+ * The result is the same as would be returned by:
+ *
+ * int.parse(const String.fromEnvironment(name, defaultValue: ""),
+ * (_) => defaultValue)
+ *
+ * Example:
+ *
+ * const int.fromEnvironment("defaultPort", defaultValue: 80)
+ */
+ external const factory int.fromEnvironment(String name, {int defaultValue});
+
+ /**
* Bit-wise and operator.
*
* Treating both `this` and [other] as sufficiently large two's component
@@ -252,12 +266,4 @@
external static int parse(String source,
{ int radix,
int onError(String source) });
-
- /**
- * Returns the integer value for the given environment variable
- * [name] or [defaultValue] if [name] is not present. If the value
- * of the environment variable is not a valid integer literal a
- * [FormatException] is thrown.
- */
- external const factory int.fromEnvironment(String name, {int defaultValue});
}
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 8da434e..799a2a9 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -125,8 +125,22 @@
}
/**
- * Returns the string for the given environment variable [name] or
- * [defaultValue] if [name] is not present.
+ * Returns the string value of the environment declaration [name].
+ *
+ * Environment declarations are provided by the surrounding system compiling
+ * or running the Dart program. Declarations map a string key to a string
+ * value.
+ *
+ * If [name] is not declared in the environment, the result is instead
+ * [defaultValue].
+ *
+ * Example of getting a value:
+ *
+ * const String.fromEnvironment("defaultFloo", defaultValue: "no floo")
+ *
+ * Example of checking whether a declaration is there at all:
+ *
+ * var isDeclared = const String.fromEnvironment("maybeDeclared") != null;
*/
external const factory String.fromEnvironment(String name,
{String defaultValue});
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 62b96f2..3a6983a 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -12601,37 +12601,58 @@
// BSD-style license that can be found in the LICENSE file.
-/**
- * A utility for retrieving data from a URL.
- *
- * HttpRequest can be used to obtain data from http, ftp, and file
- * protocols.
- *
- * For example, suppose we're developing these API docs, and we
- * wish to retrieve the HTML of the top-level page and print it out.
- * The easiest way to do that would be:
- *
- * HttpRequest.getString('http://api.dartlang.org').then((response) {
- * print(response);
- * });
- *
- * **Important**: With the default behavior of this class, your
- * code making the request should be served from the same origin (domain name,
- * port, and application layer protocol) as the URL you are trying to access
- * with HttpRequest. However, there are ways to
- * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#note-on-jsonp).
- *
- * See also:
- *
- * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
- * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
- * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
+ /**
+ * A client-side XHR request for getting data from a URL,
+ * formally known as XMLHttpRequest.
+ *
+ * HttpRequest can be used to obtain data from HTTP and FTP protocols,
+ * and is useful for AJAX-style page updates.
+ *
+ * The simplest way to get the contents of a text file, such as a
+ * JSON-formatted file, is with [getString].
+ * For example, the following code gets the contents of a JSON file
+ * and prints its length:
+ *
+ * var path = 'myData.json';
+ * HttpRequest.getString(path)
+ * .then((String fileContents) {
+ * print(fileContents.length);
+ * })
+ * .catchError((Error error) {
+ * print(error.toString());
+ * });
+ *
+ * ## Fetching data from other servers
+ *
+ * For security reasons, browsers impose restrictions on requests
+ * made by embedded apps.
+ * With the default behavior of this class,
+ * the code making the request must be served from the same origin
+ * (domain name, port, and application layer protocol)
+ * as the requested resource.
+ * In the example above, the myData.json file must be co-located with the
+ * app that uses it.
+ * You might be able to
+ * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
+ * by using CORS headers or JSONP.
+ *
+ * ## Other resources
+ *
+ * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
+ * a tutorial from _A Game of Darts_,
+ * shows two different ways to use HttpRequest to get a JSON file.
+ * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
+ * another tutorial from _A Game of Darts_,
+ * shows using HttpRequest with a custom server.
+ * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
+ * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
+ * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
*/
@DomName('XMLHttpRequest')
class HttpRequest extends HttpRequestEventTarget native "XMLHttpRequest" {
/**
- * Creates a URL get request for the specified [url].
+ * Creates a GET request for the specified [url].
*
* The server response must be a `text/` mime type for this request to
* succeed.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 302dad6..51bfff9 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -13142,37 +13142,58 @@
// BSD-style license that can be found in the LICENSE file.
-/**
- * A utility for retrieving data from a URL.
- *
- * HttpRequest can be used to obtain data from http, ftp, and file
- * protocols.
- *
- * For example, suppose we're developing these API docs, and we
- * wish to retrieve the HTML of the top-level page and print it out.
- * The easiest way to do that would be:
- *
- * HttpRequest.getString('http://api.dartlang.org').then((response) {
- * print(response);
- * });
- *
- * **Important**: With the default behavior of this class, your
- * code making the request should be served from the same origin (domain name,
- * port, and application layer protocol) as the URL you are trying to access
- * with HttpRequest. However, there are ways to
- * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#note-on-jsonp).
- *
- * See also:
- *
- * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
- * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
- * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
+ /**
+ * A client-side XHR request for getting data from a URL,
+ * formally known as XMLHttpRequest.
+ *
+ * HttpRequest can be used to obtain data from HTTP and FTP protocols,
+ * and is useful for AJAX-style page updates.
+ *
+ * The simplest way to get the contents of a text file, such as a
+ * JSON-formatted file, is with [getString].
+ * For example, the following code gets the contents of a JSON file
+ * and prints its length:
+ *
+ * var path = 'myData.json';
+ * HttpRequest.getString(path)
+ * .then((String fileContents) {
+ * print(fileContents.length);
+ * })
+ * .catchError((Error error) {
+ * print(error.toString());
+ * });
+ *
+ * ## Fetching data from other servers
+ *
+ * For security reasons, browsers impose restrictions on requests
+ * made by embedded apps.
+ * With the default behavior of this class,
+ * the code making the request must be served from the same origin
+ * (domain name, port, and application layer protocol)
+ * as the requested resource.
+ * In the example above, the myData.json file must be co-located with the
+ * app that uses it.
+ * You might be able to
+ * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
+ * by using CORS headers or JSONP.
+ *
+ * ## Other resources
+ *
+ * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
+ * a tutorial from _A Game of Darts_,
+ * shows two different ways to use HttpRequest to get a JSON file.
+ * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
+ * another tutorial from _A Game of Darts_,
+ * shows using HttpRequest with a custom server.
+ * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
+ * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
+ * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
*/
@DomName('XMLHttpRequest')
class HttpRequest extends HttpRequestEventTarget {
/**
- * Creates a URL get request for the specified [url].
+ * Creates a GET request for the specified [url].
*
* The server response must be a `text/` mime type for this request to
* succeed.
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 12375dd..1063952 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -539,20 +539,7 @@
[Map<Symbol, dynamic> namedArguments]);
/**
- * Looks up the value of a name in the scope of the closure. The
- * result is a mirror on that value.
- *
- * Let *s* be the contents of the string used to construct the symbol [name].
- *
- * If the expression *s* occurs within the source code of the reflectee,
- * and if any such occurrence refers to a declaration outside the reflectee,
- * then let *v* be the result of evaluating the expression *s* at such
- * an occurrence.
- * If *s = this*, and the reflectee was defined within the instance scope of
- * an object *o*, then let *v* be *o*.
- *
- * The returned value is the result of invoking the method [reflect] on
- * *v*.
+ * Not yet supported. Calling this method throws an [UnsupportedError].
*/
InstanceMirror findInContext(Symbol name, {ifAbsent: null});
}
diff --git a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
index 57c371e..e354001 100644
--- a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
+++ b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
@@ -1097,7 +1097,7 @@
return mx | my << 1 | mz << 2 | mw << 3;
}
- /// Mask passed to [shuffle].
+ /// Mask passed to [shuffle] and [shuffleMix].
static const int XXXX = 0x0;
static const int XXXY = 0x40;
static const int XXXZ = 0x80;
@@ -1357,7 +1357,7 @@
/// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
Float32x4 shuffle(int m) {
- if (m < 0 || m > 255) {
+ if ((m < 0) || (m > 255)) {
throw new RangeError('mask $m must be in the range [0..256)');
}
double _x = _storage[m & 0x3];
@@ -1367,53 +1367,17 @@
return new Float32x4(_x, _y, _z, _w);
}
- /// Returns a new [Float32x4] with values in the X and Y lanes
- /// replaced with the values in the Z and W lanes of [other].
- Float32x4 withZWInXY(Float32x4 other) {
- double _x = other._storage[2];
- double _y = other._storage[3];
- double _z = _storage[2];
- double _w = _storage[3];
- return new Float32x4(_x, _y, _z, _w);
- }
-
- /// Returns a new [Float32x4] with the X and Y lane values
- /// from [this] and [other] interleaved.
- Float32x4 interleaveXY(Float32x4 other) {
- double _x = _storage[0];
- double _y = other._storage[0];
- double _z = _storage[1];
- double _w = other._storage[1];
- return new Float32x4(_x, _y, _z, _w);
- }
-
- /// Returns a new [Float32x4] with the Z and W lane values
- /// from [this] and [other] interleaved.
- Float32x4 interleaveZW(Float32x4 other) {
- double _x = _storage[2];
- double _y = other._storage[2];
- double _z = _storage[3];
- double _w = other._storage[3];
- return new Float32x4(_x, _y, _z, _w);
- }
-
- /// Returns a new [Float32x4] with the X and Y lane value pairs
- /// from [this] and [other] interleaved.
- Float32x4 interleaveXYPairs(Float32x4 other) {
- double _x = _storage[0];
- double _y = _storage[1];
- double _z = other._storage[0];
- double _w = other._storage[1];
- return new Float32x4(_x, _y, _z, _w);
- }
-
- /// Returns a new [Float32x4] with the Z and W lane value pairs
- /// from [this] and [other] interleaved.
- Float32x4 interleaveZWPairs(Float32x4 other) {
- double _x = _storage[2];
- double _y = _storage[3];
- double _z = other._storage[2];
- double _w = other._storage[3];
+ /// Shuffle the lane values in [this] and [other]. The returned
+ /// Float32x4 will have XY lanes from [this] and ZW lanes from [other].
+ /// Uses the same [mask] as [shuffle].
+ Float32x4 shuffleMix(Float32x4 other, int m) {
+ if ((m < 0) || (m > 255)) {
+ throw new RangeError('mask $m must be in the range [0..256)');
+ }
+ double _x = _storage[m & 0x3];
+ double _y = _storage[(m >> 2) & 0x3];
+ double _z = other._storage[(m >> 4) & 0x3];
+ double _w = other._storage[(m >> 6) & 0x3];
return new Float32x4(_x, _y, _z, _w);
}
@@ -1597,6 +1561,290 @@
return mx | my << 1 | mz << 2 | mw << 3;
}
+ /// Mask passed to [shuffle] and [shuffleMix].
+ static const int XXXX = 0x0;
+ static const int XXXY = 0x40;
+ static const int XXXZ = 0x80;
+ static const int XXXW = 0xC0;
+ static const int XXYX = 0x10;
+ static const int XXYY = 0x50;
+ static const int XXYZ = 0x90;
+ static const int XXYW = 0xD0;
+ static const int XXZX = 0x20;
+ static const int XXZY = 0x60;
+ static const int XXZZ = 0xA0;
+ static const int XXZW = 0xE0;
+ static const int XXWX = 0x30;
+ static const int XXWY = 0x70;
+ static const int XXWZ = 0xB0;
+ static const int XXWW = 0xF0;
+ static const int XYXX = 0x4;
+ static const int XYXY = 0x44;
+ static const int XYXZ = 0x84;
+ static const int XYXW = 0xC4;
+ static const int XYYX = 0x14;
+ static const int XYYY = 0x54;
+ static const int XYYZ = 0x94;
+ static const int XYYW = 0xD4;
+ static const int XYZX = 0x24;
+ static const int XYZY = 0x64;
+ static const int XYZZ = 0xA4;
+ static const int XYZW = 0xE4;
+ static const int XYWX = 0x34;
+ static const int XYWY = 0x74;
+ static const int XYWZ = 0xB4;
+ static const int XYWW = 0xF4;
+ static const int XZXX = 0x8;
+ static const int XZXY = 0x48;
+ static const int XZXZ = 0x88;
+ static const int XZXW = 0xC8;
+ static const int XZYX = 0x18;
+ static const int XZYY = 0x58;
+ static const int XZYZ = 0x98;
+ static const int XZYW = 0xD8;
+ static const int XZZX = 0x28;
+ static const int XZZY = 0x68;
+ static const int XZZZ = 0xA8;
+ static const int XZZW = 0xE8;
+ static const int XZWX = 0x38;
+ static const int XZWY = 0x78;
+ static const int XZWZ = 0xB8;
+ static const int XZWW = 0xF8;
+ static const int XWXX = 0xC;
+ static const int XWXY = 0x4C;
+ static const int XWXZ = 0x8C;
+ static const int XWXW = 0xCC;
+ static const int XWYX = 0x1C;
+ static const int XWYY = 0x5C;
+ static const int XWYZ = 0x9C;
+ static const int XWYW = 0xDC;
+ static const int XWZX = 0x2C;
+ static const int XWZY = 0x6C;
+ static const int XWZZ = 0xAC;
+ static const int XWZW = 0xEC;
+ static const int XWWX = 0x3C;
+ static const int XWWY = 0x7C;
+ static const int XWWZ = 0xBC;
+ static const int XWWW = 0xFC;
+ static const int YXXX = 0x1;
+ static const int YXXY = 0x41;
+ static const int YXXZ = 0x81;
+ static const int YXXW = 0xC1;
+ static const int YXYX = 0x11;
+ static const int YXYY = 0x51;
+ static const int YXYZ = 0x91;
+ static const int YXYW = 0xD1;
+ static const int YXZX = 0x21;
+ static const int YXZY = 0x61;
+ static const int YXZZ = 0xA1;
+ static const int YXZW = 0xE1;
+ static const int YXWX = 0x31;
+ static const int YXWY = 0x71;
+ static const int YXWZ = 0xB1;
+ static const int YXWW = 0xF1;
+ static const int YYXX = 0x5;
+ static const int YYXY = 0x45;
+ static const int YYXZ = 0x85;
+ static const int YYXW = 0xC5;
+ static const int YYYX = 0x15;
+ static const int YYYY = 0x55;
+ static const int YYYZ = 0x95;
+ static const int YYYW = 0xD5;
+ static const int YYZX = 0x25;
+ static const int YYZY = 0x65;
+ static const int YYZZ = 0xA5;
+ static const int YYZW = 0xE5;
+ static const int YYWX = 0x35;
+ static const int YYWY = 0x75;
+ static const int YYWZ = 0xB5;
+ static const int YYWW = 0xF5;
+ static const int YZXX = 0x9;
+ static const int YZXY = 0x49;
+ static const int YZXZ = 0x89;
+ static const int YZXW = 0xC9;
+ static const int YZYX = 0x19;
+ static const int YZYY = 0x59;
+ static const int YZYZ = 0x99;
+ static const int YZYW = 0xD9;
+ static const int YZZX = 0x29;
+ static const int YZZY = 0x69;
+ static const int YZZZ = 0xA9;
+ static const int YZZW = 0xE9;
+ static const int YZWX = 0x39;
+ static const int YZWY = 0x79;
+ static const int YZWZ = 0xB9;
+ static const int YZWW = 0xF9;
+ static const int YWXX = 0xD;
+ static const int YWXY = 0x4D;
+ static const int YWXZ = 0x8D;
+ static const int YWXW = 0xCD;
+ static const int YWYX = 0x1D;
+ static const int YWYY = 0x5D;
+ static const int YWYZ = 0x9D;
+ static const int YWYW = 0xDD;
+ static const int YWZX = 0x2D;
+ static const int YWZY = 0x6D;
+ static const int YWZZ = 0xAD;
+ static const int YWZW = 0xED;
+ static const int YWWX = 0x3D;
+ static const int YWWY = 0x7D;
+ static const int YWWZ = 0xBD;
+ static const int YWWW = 0xFD;
+ static const int ZXXX = 0x2;
+ static const int ZXXY = 0x42;
+ static const int ZXXZ = 0x82;
+ static const int ZXXW = 0xC2;
+ static const int ZXYX = 0x12;
+ static const int ZXYY = 0x52;
+ static const int ZXYZ = 0x92;
+ static const int ZXYW = 0xD2;
+ static const int ZXZX = 0x22;
+ static const int ZXZY = 0x62;
+ static const int ZXZZ = 0xA2;
+ static const int ZXZW = 0xE2;
+ static const int ZXWX = 0x32;
+ static const int ZXWY = 0x72;
+ static const int ZXWZ = 0xB2;
+ static const int ZXWW = 0xF2;
+ static const int ZYXX = 0x6;
+ static const int ZYXY = 0x46;
+ static const int ZYXZ = 0x86;
+ static const int ZYXW = 0xC6;
+ static const int ZYYX = 0x16;
+ static const int ZYYY = 0x56;
+ static const int ZYYZ = 0x96;
+ static const int ZYYW = 0xD6;
+ static const int ZYZX = 0x26;
+ static const int ZYZY = 0x66;
+ static const int ZYZZ = 0xA6;
+ static const int ZYZW = 0xE6;
+ static const int ZYWX = 0x36;
+ static const int ZYWY = 0x76;
+ static const int ZYWZ = 0xB6;
+ static const int ZYWW = 0xF6;
+ static const int ZZXX = 0xA;
+ static const int ZZXY = 0x4A;
+ static const int ZZXZ = 0x8A;
+ static const int ZZXW = 0xCA;
+ static const int ZZYX = 0x1A;
+ static const int ZZYY = 0x5A;
+ static const int ZZYZ = 0x9A;
+ static const int ZZYW = 0xDA;
+ static const int ZZZX = 0x2A;
+ static const int ZZZY = 0x6A;
+ static const int ZZZZ = 0xAA;
+ static const int ZZZW = 0xEA;
+ static const int ZZWX = 0x3A;
+ static const int ZZWY = 0x7A;
+ static const int ZZWZ = 0xBA;
+ static const int ZZWW = 0xFA;
+ static const int ZWXX = 0xE;
+ static const int ZWXY = 0x4E;
+ static const int ZWXZ = 0x8E;
+ static const int ZWXW = 0xCE;
+ static const int ZWYX = 0x1E;
+ static const int ZWYY = 0x5E;
+ static const int ZWYZ = 0x9E;
+ static const int ZWYW = 0xDE;
+ static const int ZWZX = 0x2E;
+ static const int ZWZY = 0x6E;
+ static const int ZWZZ = 0xAE;
+ static const int ZWZW = 0xEE;
+ static const int ZWWX = 0x3E;
+ static const int ZWWY = 0x7E;
+ static const int ZWWZ = 0xBE;
+ static const int ZWWW = 0xFE;
+ static const int WXXX = 0x3;
+ static const int WXXY = 0x43;
+ static const int WXXZ = 0x83;
+ static const int WXXW = 0xC3;
+ static const int WXYX = 0x13;
+ static const int WXYY = 0x53;
+ static const int WXYZ = 0x93;
+ static const int WXYW = 0xD3;
+ static const int WXZX = 0x23;
+ static const int WXZY = 0x63;
+ static const int WXZZ = 0xA3;
+ static const int WXZW = 0xE3;
+ static const int WXWX = 0x33;
+ static const int WXWY = 0x73;
+ static const int WXWZ = 0xB3;
+ static const int WXWW = 0xF3;
+ static const int WYXX = 0x7;
+ static const int WYXY = 0x47;
+ static const int WYXZ = 0x87;
+ static const int WYXW = 0xC7;
+ static const int WYYX = 0x17;
+ static const int WYYY = 0x57;
+ static const int WYYZ = 0x97;
+ static const int WYYW = 0xD7;
+ static const int WYZX = 0x27;
+ static const int WYZY = 0x67;
+ static const int WYZZ = 0xA7;
+ static const int WYZW = 0xE7;
+ static const int WYWX = 0x37;
+ static const int WYWY = 0x77;
+ static const int WYWZ = 0xB7;
+ static const int WYWW = 0xF7;
+ static const int WZXX = 0xB;
+ static const int WZXY = 0x4B;
+ static const int WZXZ = 0x8B;
+ static const int WZXW = 0xCB;
+ static const int WZYX = 0x1B;
+ static const int WZYY = 0x5B;
+ static const int WZYZ = 0x9B;
+ static const int WZYW = 0xDB;
+ static const int WZZX = 0x2B;
+ static const int WZZY = 0x6B;
+ static const int WZZZ = 0xAB;
+ static const int WZZW = 0xEB;
+ static const int WZWX = 0x3B;
+ static const int WZWY = 0x7B;
+ static const int WZWZ = 0xBB;
+ static const int WZWW = 0xFB;
+ static const int WWXX = 0xF;
+ static const int WWXY = 0x4F;
+ static const int WWXZ = 0x8F;
+ static const int WWXW = 0xCF;
+ static const int WWYX = 0x1F;
+ static const int WWYY = 0x5F;
+ static const int WWYZ = 0x9F;
+ static const int WWYW = 0xDF;
+ static const int WWZX = 0x2F;
+ static const int WWZY = 0x6F;
+ static const int WWZZ = 0xAF;
+ static const int WWZW = 0xEF;
+ static const int WWWX = 0x3F;
+ static const int WWWY = 0x7F;
+ static const int WWWZ = 0xBF;
+ static const int WWWW = 0xFF;
+
+ /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+ Uint32x4 shuffle(int mask) {
+ if ((mask < 0) || (mask > 255)) {
+ throw new RangeError('mask $mask must be in the range [0..256)');
+ }
+ int _x = _storage[mask & 0x3];
+ int _y = _storage[(mask >> 2) & 0x3];
+ int _z = _storage[(mask >> 4) & 0x3];
+ int _w = _storage[(mask >> 6) & 0x3];
+ return new Uint32x4(_x, _y, _z, _w);
+ }
+
+ /// Shuffle the lane values in [this] and [other]. The returned
+ /// Uint32x4 will have XY lanes from [this] and ZW lanes from [other].
+ /// Uses the same [mask] as [shuffle].
+ Uint32x4 shuffleMix(Uint32x4 other, int mask) {
+ if ((mask < 0) || (mask > 255)) {
+ throw new RangeError('mask $mask must be in the range [0..256)');
+ }
+ int _x = _storage[mask & 0x3];
+ int _y = _storage[(mask >> 2) & 0x3];
+ int _z = other._storage[(mask >> 4) & 0x3];
+ int _w = other._storage[(mask >> 6) & 0x3];
+ return new Uint32x4(_x, _y, _z, _w);
+ }
+
/// Returns a new [Uint32x4] copied from [this] with a new x value.
Uint32x4 withX(int x) {
int _x = x;
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 398a360..d23d384 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -921,7 +921,7 @@
/// Extract the sign bits from each lane return them in the first 4 bits.
int get signMask;
- /// Mask passed to [shuffle].
+ /// Mask passed to [shuffle] or [shuffleMix].
static const int XXXX = 0x0;
static const int XXXY = 0x40;
static const int XXXZ = 0x80;
@@ -1182,25 +1182,10 @@
/// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
Float32x4 shuffle(int mask);
- /// Returns a new [Float32x4] with values in the X and Y lanes
- /// replaced with the values in the Z and W lanes of [other].
- Float32x4 withZWInXY(Float32x4 other);
-
- /// Returns a new [Float32x4] with the X and Y lane values
- /// from [this] and [other] interleaved.
- Float32x4 interleaveXY(Float32x4 other);
-
- /// Returns a new [Float32x4] with the Z and W lane values
- /// from [this] and [other] interleaved.
- Float32x4 interleaveZW(Float32x4 other);
-
- /// Returns a new [Float32x4] with the X and Y lane value pairs
- /// from [this] and [other] interleaved.
- Float32x4 interleaveXYPairs(Float32x4 other);
-
- /// Returns a new [Float32x4] with the Z and W lane value pairs
- /// from [this] and [other] interleaved.
- Float32x4 interleaveZWPairs(Float32x4 other);
+ /// Shuffle the lane values in [this] and [other]. The returned
+ /// Float32x4 will have XY lanes from [this] and ZW lanes from [other].
+ /// Uses the same [mask] as [shuffle].
+ Float32x4 shuffleMix(Float32x4 other, int mask);
/// Returns a new [Float32x4] copied from [this] with a new x value.
Float32x4 withX(double x);
@@ -1261,6 +1246,272 @@
/// Extract the top bit from each lane return them in the first 4 bits.
int get signMask;
+ /// Mask passed to [shuffle] or [shuffleMix].
+ static const int XXXX = 0x0;
+ static const int XXXY = 0x40;
+ static const int XXXZ = 0x80;
+ static const int XXXW = 0xC0;
+ static const int XXYX = 0x10;
+ static const int XXYY = 0x50;
+ static const int XXYZ = 0x90;
+ static const int XXYW = 0xD0;
+ static const int XXZX = 0x20;
+ static const int XXZY = 0x60;
+ static const int XXZZ = 0xA0;
+ static const int XXZW = 0xE0;
+ static const int XXWX = 0x30;
+ static const int XXWY = 0x70;
+ static const int XXWZ = 0xB0;
+ static const int XXWW = 0xF0;
+ static const int XYXX = 0x4;
+ static const int XYXY = 0x44;
+ static const int XYXZ = 0x84;
+ static const int XYXW = 0xC4;
+ static const int XYYX = 0x14;
+ static const int XYYY = 0x54;
+ static const int XYYZ = 0x94;
+ static const int XYYW = 0xD4;
+ static const int XYZX = 0x24;
+ static const int XYZY = 0x64;
+ static const int XYZZ = 0xA4;
+ static const int XYZW = 0xE4;
+ static const int XYWX = 0x34;
+ static const int XYWY = 0x74;
+ static const int XYWZ = 0xB4;
+ static const int XYWW = 0xF4;
+ static const int XZXX = 0x8;
+ static const int XZXY = 0x48;
+ static const int XZXZ = 0x88;
+ static const int XZXW = 0xC8;
+ static const int XZYX = 0x18;
+ static const int XZYY = 0x58;
+ static const int XZYZ = 0x98;
+ static const int XZYW = 0xD8;
+ static const int XZZX = 0x28;
+ static const int XZZY = 0x68;
+ static const int XZZZ = 0xA8;
+ static const int XZZW = 0xE8;
+ static const int XZWX = 0x38;
+ static const int XZWY = 0x78;
+ static const int XZWZ = 0xB8;
+ static const int XZWW = 0xF8;
+ static const int XWXX = 0xC;
+ static const int XWXY = 0x4C;
+ static const int XWXZ = 0x8C;
+ static const int XWXW = 0xCC;
+ static const int XWYX = 0x1C;
+ static const int XWYY = 0x5C;
+ static const int XWYZ = 0x9C;
+ static const int XWYW = 0xDC;
+ static const int XWZX = 0x2C;
+ static const int XWZY = 0x6C;
+ static const int XWZZ = 0xAC;
+ static const int XWZW = 0xEC;
+ static const int XWWX = 0x3C;
+ static const int XWWY = 0x7C;
+ static const int XWWZ = 0xBC;
+ static const int XWWW = 0xFC;
+ static const int YXXX = 0x1;
+ static const int YXXY = 0x41;
+ static const int YXXZ = 0x81;
+ static const int YXXW = 0xC1;
+ static const int YXYX = 0x11;
+ static const int YXYY = 0x51;
+ static const int YXYZ = 0x91;
+ static const int YXYW = 0xD1;
+ static const int YXZX = 0x21;
+ static const int YXZY = 0x61;
+ static const int YXZZ = 0xA1;
+ static const int YXZW = 0xE1;
+ static const int YXWX = 0x31;
+ static const int YXWY = 0x71;
+ static const int YXWZ = 0xB1;
+ static const int YXWW = 0xF1;
+ static const int YYXX = 0x5;
+ static const int YYXY = 0x45;
+ static const int YYXZ = 0x85;
+ static const int YYXW = 0xC5;
+ static const int YYYX = 0x15;
+ static const int YYYY = 0x55;
+ static const int YYYZ = 0x95;
+ static const int YYYW = 0xD5;
+ static const int YYZX = 0x25;
+ static const int YYZY = 0x65;
+ static const int YYZZ = 0xA5;
+ static const int YYZW = 0xE5;
+ static const int YYWX = 0x35;
+ static const int YYWY = 0x75;
+ static const int YYWZ = 0xB5;
+ static const int YYWW = 0xF5;
+ static const int YZXX = 0x9;
+ static const int YZXY = 0x49;
+ static const int YZXZ = 0x89;
+ static const int YZXW = 0xC9;
+ static const int YZYX = 0x19;
+ static const int YZYY = 0x59;
+ static const int YZYZ = 0x99;
+ static const int YZYW = 0xD9;
+ static const int YZZX = 0x29;
+ static const int YZZY = 0x69;
+ static const int YZZZ = 0xA9;
+ static const int YZZW = 0xE9;
+ static const int YZWX = 0x39;
+ static const int YZWY = 0x79;
+ static const int YZWZ = 0xB9;
+ static const int YZWW = 0xF9;
+ static const int YWXX = 0xD;
+ static const int YWXY = 0x4D;
+ static const int YWXZ = 0x8D;
+ static const int YWXW = 0xCD;
+ static const int YWYX = 0x1D;
+ static const int YWYY = 0x5D;
+ static const int YWYZ = 0x9D;
+ static const int YWYW = 0xDD;
+ static const int YWZX = 0x2D;
+ static const int YWZY = 0x6D;
+ static const int YWZZ = 0xAD;
+ static const int YWZW = 0xED;
+ static const int YWWX = 0x3D;
+ static const int YWWY = 0x7D;
+ static const int YWWZ = 0xBD;
+ static const int YWWW = 0xFD;
+ static const int ZXXX = 0x2;
+ static const int ZXXY = 0x42;
+ static const int ZXXZ = 0x82;
+ static const int ZXXW = 0xC2;
+ static const int ZXYX = 0x12;
+ static const int ZXYY = 0x52;
+ static const int ZXYZ = 0x92;
+ static const int ZXYW = 0xD2;
+ static const int ZXZX = 0x22;
+ static const int ZXZY = 0x62;
+ static const int ZXZZ = 0xA2;
+ static const int ZXZW = 0xE2;
+ static const int ZXWX = 0x32;
+ static const int ZXWY = 0x72;
+ static const int ZXWZ = 0xB2;
+ static const int ZXWW = 0xF2;
+ static const int ZYXX = 0x6;
+ static const int ZYXY = 0x46;
+ static const int ZYXZ = 0x86;
+ static const int ZYXW = 0xC6;
+ static const int ZYYX = 0x16;
+ static const int ZYYY = 0x56;
+ static const int ZYYZ = 0x96;
+ static const int ZYYW = 0xD6;
+ static const int ZYZX = 0x26;
+ static const int ZYZY = 0x66;
+ static const int ZYZZ = 0xA6;
+ static const int ZYZW = 0xE6;
+ static const int ZYWX = 0x36;
+ static const int ZYWY = 0x76;
+ static const int ZYWZ = 0xB6;
+ static const int ZYWW = 0xF6;
+ static const int ZZXX = 0xA;
+ static const int ZZXY = 0x4A;
+ static const int ZZXZ = 0x8A;
+ static const int ZZXW = 0xCA;
+ static const int ZZYX = 0x1A;
+ static const int ZZYY = 0x5A;
+ static const int ZZYZ = 0x9A;
+ static const int ZZYW = 0xDA;
+ static const int ZZZX = 0x2A;
+ static const int ZZZY = 0x6A;
+ static const int ZZZZ = 0xAA;
+ static const int ZZZW = 0xEA;
+ static const int ZZWX = 0x3A;
+ static const int ZZWY = 0x7A;
+ static const int ZZWZ = 0xBA;
+ static const int ZZWW = 0xFA;
+ static const int ZWXX = 0xE;
+ static const int ZWXY = 0x4E;
+ static const int ZWXZ = 0x8E;
+ static const int ZWXW = 0xCE;
+ static const int ZWYX = 0x1E;
+ static const int ZWYY = 0x5E;
+ static const int ZWYZ = 0x9E;
+ static const int ZWYW = 0xDE;
+ static const int ZWZX = 0x2E;
+ static const int ZWZY = 0x6E;
+ static const int ZWZZ = 0xAE;
+ static const int ZWZW = 0xEE;
+ static const int ZWWX = 0x3E;
+ static const int ZWWY = 0x7E;
+ static const int ZWWZ = 0xBE;
+ static const int ZWWW = 0xFE;
+ static const int WXXX = 0x3;
+ static const int WXXY = 0x43;
+ static const int WXXZ = 0x83;
+ static const int WXXW = 0xC3;
+ static const int WXYX = 0x13;
+ static const int WXYY = 0x53;
+ static const int WXYZ = 0x93;
+ static const int WXYW = 0xD3;
+ static const int WXZX = 0x23;
+ static const int WXZY = 0x63;
+ static const int WXZZ = 0xA3;
+ static const int WXZW = 0xE3;
+ static const int WXWX = 0x33;
+ static const int WXWY = 0x73;
+ static const int WXWZ = 0xB3;
+ static const int WXWW = 0xF3;
+ static const int WYXX = 0x7;
+ static const int WYXY = 0x47;
+ static const int WYXZ = 0x87;
+ static const int WYXW = 0xC7;
+ static const int WYYX = 0x17;
+ static const int WYYY = 0x57;
+ static const int WYYZ = 0x97;
+ static const int WYYW = 0xD7;
+ static const int WYZX = 0x27;
+ static const int WYZY = 0x67;
+ static const int WYZZ = 0xA7;
+ static const int WYZW = 0xE7;
+ static const int WYWX = 0x37;
+ static const int WYWY = 0x77;
+ static const int WYWZ = 0xB7;
+ static const int WYWW = 0xF7;
+ static const int WZXX = 0xB;
+ static const int WZXY = 0x4B;
+ static const int WZXZ = 0x8B;
+ static const int WZXW = 0xCB;
+ static const int WZYX = 0x1B;
+ static const int WZYY = 0x5B;
+ static const int WZYZ = 0x9B;
+ static const int WZYW = 0xDB;
+ static const int WZZX = 0x2B;
+ static const int WZZY = 0x6B;
+ static const int WZZZ = 0xAB;
+ static const int WZZW = 0xEB;
+ static const int WZWX = 0x3B;
+ static const int WZWY = 0x7B;
+ static const int WZWZ = 0xBB;
+ static const int WZWW = 0xFB;
+ static const int WWXX = 0xF;
+ static const int WWXY = 0x4F;
+ static const int WWXZ = 0x8F;
+ static const int WWXW = 0xCF;
+ static const int WWYX = 0x1F;
+ static const int WWYY = 0x5F;
+ static const int WWYZ = 0x9F;
+ static const int WWYW = 0xDF;
+ static const int WWZX = 0x2F;
+ static const int WWZY = 0x6F;
+ static const int WWZZ = 0xAF;
+ static const int WWZW = 0xEF;
+ static const int WWWX = 0x3F;
+ static const int WWWY = 0x7F;
+ static const int WWWZ = 0xBF;
+ static const int WWWW = 0xFF;
+
+ /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+ Uint32x4 shuffle(int mask);
+
+ /// Shuffle the lane values in [this] and [other]. The returned
+ /// Uint32x4 will have XY lanes from [this] and ZW lanes from [other].
+ /// Uses the same [mask] as [shuffle].
+ Uint32x4 shuffleMix(Uint32x4 other, int mask);
+
/// Returns a new [Uint32x4] copied from [this] with a new x value.
Uint32x4 withX(int x);
/// Returns a new [Uint32x4] copied from [this] with a new y value.
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 7d88a47f..da0374b 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -71,6 +71,13 @@
# co19 issue #623: main() { {}; } is block and empty statement, not a map
Language/13_Statements/02_Expression_Statements_A01_t13: Fail, OK
+# co19 issue #650: two argument shuffles have been refactored.
+LibTest/typed_data/Float32x4/interleaveZWPairs_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveZW_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/withZWInXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXYPairs_A01_t01: Fail # co19 issue 650
+
# co19 issue #626: StreamTransformers have been refactored.
LibTest/async/EventTransformStream/EventTransformStream_A01_t01: Fail
LibTest/async/EventTransformStream/EventTransformStream_A01_t02: Fail
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 4df2aa6..6e93f45 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -88,9 +88,6 @@
LibTest/core/Uri/toFilePath_A01_t01: pass, fail, ok # co19 Issue 592
-LibTest/async/Stream/handleError_A04_t02: Fail # co19-roll r641: Please triage this failure
-LibTest/async/Stream/listen_A05_t02: Fail # co19-roll r641: Please triage this failure
-LibTest/async/StreamSink/addError_A01_t01: Fail # co19-roll r641: Please triage this failure
LibTest/async/StreamSink/addStream_A01_t02: Timeout, Fail, OK # Dart issue 14334 - test is also incorrect.
LibTest/collection/ListBase/ListBase_class_A01_t01: Fail, Timeout # co19-roll r641: Please triage this failure
LibTest/collection/ListMixin/ListMixin_class_A01_t01: Fail, Timeout # co19-roll r641: Please triage this failure
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 0091d34..e7f75af 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -67,6 +67,11 @@
LibTest/math/exp_A01_t01: Fail # Issue co19 - 44
LibTest/math/sin_A01_t01: Fail # Inherited from VM.
LibTest/math/tan_A01_t01: Fail # Issue co19 - 44
+LibTest/typed_data/Float32x4/interleaveZWPairs_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveZW_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/withZWInXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXYPairs_A01_t01: Fail # co19 issue 650
[ $compiler == dart2dart && $system == windows ]
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 73161a3..1a5e702 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -53,6 +53,11 @@
LibTest/typed_data/Uint32List/Uint32List_A02_t01: fail # co19-roll r576: Please triage this failure
LibTest/typed_data/Uint8ClampedList/Uint8ClampedList_A02_t01: fail # co19-roll r576: Please triage this failure
LibTest/typed_data/Uint8List/Uint8List_A02_t01: fail # co19-roll r576: Please triage this failure
+LibTest/typed_data/Float32x4/interleaveZWPairs_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveZW_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/withZWInXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXYPairs_A01_t01: Fail # co19 issue 650
[ $compiler == dart2js && $runtime != ie9 ]
LibTest/typed_data/ByteData/ByteData_A02_t01: fail # co19-roll r576: Please triage this failure
@@ -445,7 +450,6 @@
Language/14_Libraries_and_Scripts/5_URIs_A01_t21: fail # co19-roll r546: Please triage this failure
Language/15_Types/4_Interface_Types_A11_t01: crash # co19-roll r546: Please triage this failure
Language/15_Types/4_Interface_Types_A11_t02: crash # co19-roll r546: Please triage this failure
-Language/15_Types/4_Interface_Types_A11_t04: fail # co19-roll r546: Please triage this failure
Language/15_Types/4_Interface_Types_A12_t10: fail # co19-roll r546: Please triage this failure
LibTest/core/DateTime/DateTime_A01_t03: fail # co19-roll r546: Please triage this failure
LibTest/core/DateTime/parse_A03_t01: fail # co19-roll r546: Please triage this failure
@@ -599,6 +603,7 @@
Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
Language/14_Libraries_and_Scripts/2_Exports_A05_t03: MissingCompileTimeError # co19-roll r623: Please triage this failure
+Language/15_Types/4_Interface_Types_A11_t04: fail # Issue 14654
LibTest/core/Symbol/Symbol_A01_t02: CompileTimeError # co19-roll r607: Please triage this failure
[ $compiler == dart2js ]
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 317c87b..6915f46 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -57,6 +57,11 @@
LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # co19-roll r607: Please triage this failure
LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # co19-roll r607: Please triage this failure
LibTest/typed_data/Float32x4/clamp_A01_t01: Pass, Fail # co19 issue 636
+LibTest/typed_data/Float32x4/interleaveZWPairs_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveZW_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/withZWInXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXYPairs_A01_t01: Fail # co19 issue 650
[ $compiler == none && $runtime == vm ]
LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # Issue 13398
diff --git a/tests/compiler/dart2js/analyze_helper.dart b/tests/compiler/dart2js/analyze_helper.dart
index affcf0d..adb0673 100644
--- a/tests/compiler/dart2js/analyze_helper.dart
+++ b/tests/compiler/dart2js/analyze_helper.dart
@@ -133,7 +133,8 @@
handler.diagnosticHandler,
libraryRoot, libraryRoot,
<String>['--analyze-only', '--analyze-all',
- '--categories=Client,Server']);
+ '--categories=Client,Server'],
+ {});
compiler.librariesToAnalyzeWhenRun = uriList;
return compiler.run(null).then((_) {
handler.checkResults();
diff --git a/tests/compiler/dart2js/bad_loop_test.dart b/tests/compiler/dart2js/bad_loop_test.dart
index ea1f03d..e8c2848 100644
--- a/tests/compiler/dart2js/bad_loop_test.dart
+++ b/tests/compiler/dart2js/bad_loop_test.dart
@@ -36,7 +36,8 @@
diagnosticHandler,
libraryRoot,
packageRoot,
- ['--analyze-only']);
+ ['--analyze-only'],
+ {});
asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
Expect.isTrue(compiler.compilationFailed);
Expect.equals(5, errorCount);
diff --git a/tests/compiler/dart2js/codegen_helper.dart b/tests/compiler/dart2js/codegen_helper.dart
index 445276e..1d1f455 100644
--- a/tests/compiler/dart2js/codegen_helper.dart
+++ b/tests/compiler/dart2js/codegen_helper.dart
@@ -21,7 +21,8 @@
handler.diagnosticHandler,
libraryRoot,
packageRoot,
- options);
+ options,
+ {});
Uri uri = Uri.parse('memory:main.dart');
return compiler.run(uri).then((success) {
Expect.isTrue(success);
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index 777c4fc..f753aad 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -26,7 +26,8 @@
handler.diagnosticHandler,
libraryRoot,
packageRoot,
- ['--analyze-only']);
+ ['--analyze-only'],
+ {});
asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
var main = compiler.mainApp.find(dart2js.Compiler.MAIN);
Expect.isNotNull(main, "Could not find 'main'");
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index 475979a..5e93e2e29 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -29,7 +29,8 @@
diagnosticHandler,
libraryRoot,
packageRoot,
- ['--analyze-only']);
+ ['--analyze-only'],
+ {});
asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
diagnostics.sort();
var expected = [
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 5d3373b..414e5cd 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -97,7 +97,8 @@
handler,
libraryRoot,
packageRoot,
- options);
+ options,
+ {});
if (cachedCompiler != null) {
compiler.coreLibrary = cachedCompiler.libraries['dart:core'];
compiler.types = cachedCompiler.types;
diff --git a/tests/compiler/dart2js/mirror_tree_shaking_test.dart b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
index 5104a48..5caab85 100644
--- a/tests/compiler/dart2js/mirror_tree_shaking_test.dart
+++ b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
@@ -41,7 +41,8 @@
diagnosticHandler,
libraryRoot,
packageRoot,
- []);
+ [],
+ {});
asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
Expect.isFalse(compiler.compilationFailed);
Expect.isFalse(compiler.enqueuer.resolution.hasEnqueuedEverything);
diff --git a/tests/compiler/dart2js/missing_file_test.dart b/tests/compiler/dart2js/missing_file_test.dart
index 0e53476..8ae236e 100644
--- a/tests/compiler/dart2js/missing_file_test.dart
+++ b/tests/compiler/dart2js/missing_file_test.dart
@@ -57,7 +57,8 @@
diagnosticHandler,
libraryRoot,
null,
- []);
+ [],
+ {});
asyncTest(() => compiler.run(main).then((_) {
Expect.equals(1, errors.length);
diff --git a/tests/compiler/dart2js/package_root_test.dart b/tests/compiler/dart2js/package_root_test.dart
index 6ff118f..c05469c 100644
--- a/tests/compiler/dart2js/package_root_test.dart
+++ b/tests/compiler/dart2js/package_root_test.dart
@@ -57,7 +57,8 @@
diagnosticHandler,
libraryRoot,
null,
- []);
+ [],
+ {});
asyncTest(() => compiler.run(main).then((_) {
Expect.equals(1, errors.length);
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index b1aeb6a..a0d433e 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -114,8 +114,9 @@
""");
compiler.resolveStatement("Bar bar;");
ClassElement classBar = compiler.mainApp.find("Bar");
- Expect.equals('[ Foo, X<Bar>, X<Foo>, Object ]',
- classBar.allSupertypes.toString());
+ Expect.equals(1, compiler.errors.length);
+ Expect.equals(0, compiler.warnings.length);
+ Expect.equals(MessageKind.MULTI_INHERITANCE, compiler.errors[0].message.kind);
}
testTypeVariables() {
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index 2d1a4d5..cd09732 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -8,39 +8,39 @@
import "../../../sdk/lib/_internal/compiler/implementation/ssa/ssa.dart";
import "../../../sdk/lib/_internal/compiler/implementation/types/types.dart";
-HType nullType;
-HType objectType;
-HType jsBoolean;
-HType jsNumber;
-HType jsInteger;
-HType jsDouble;
-HType jsBooleanOrNull;
-HType jsNumberOrNull;
-HType jsIntegerOrNull;
-HType jsDoubleOrNull;
-HType emptyType;
-HType dynamicType;
+TypeMask nullType;
+TypeMask objectType;
+TypeMask jsBoolean;
+TypeMask jsNumber;
+TypeMask jsInteger;
+TypeMask jsDouble;
+TypeMask jsBooleanOrNull;
+TypeMask jsNumberOrNull;
+TypeMask jsIntegerOrNull;
+TypeMask jsDoubleOrNull;
+TypeMask emptyType;
+TypeMask dynamicType;
var patternClass;
-HType nonPrimitive1;
-HType nonPrimitive2;
-HType potentialArray;
-HType potentialString;
-HType jsInterceptor;
+TypeMask nonPrimitive1;
+TypeMask nonPrimitive2;
+TypeMask potentialArray;
+TypeMask potentialString;
+TypeMask jsInterceptor;
-HType jsIndexable;
-HType jsReadableArray;
-HType jsMutableArray;
-HType jsFixedArray;
-HType jsExtendableArray;
-HType jsString;
-HType jsStringOrNull;
-HType jsArrayOrNull;
-HType jsMutableArrayOrNull;
-HType jsFixedArrayOrNull;
-HType jsExtendableArrayOrNull;
-HType jsIndexableOrNull;
-HType jsInterceptorOrNull;
+TypeMask jsIndexable;
+TypeMask jsReadableArray;
+TypeMask jsMutableArray;
+TypeMask jsFixedArray;
+TypeMask jsExtendableArray;
+TypeMask jsString;
+TypeMask jsStringOrNull;
+TypeMask jsArrayOrNull;
+TypeMask jsMutableArrayOrNull;
+TypeMask jsFixedArrayOrNull;
+TypeMask jsExtendableArrayOrNull;
+TypeMask jsIndexableOrNull;
+TypeMask jsInterceptorOrNull;
class Pair {
@@ -376,8 +376,8 @@
check(nonPrimitive1, nullType, (type) => type is HBoundedType);
check(nonPrimitive2, nullType, (type) => type is HBoundedType);
- check(nullType, nonPrimitive1, (type) => type.canBeNull());
- check(nullType, nonPrimitive2, (type) => type.canBeNull());
+ check(nullType, nonPrimitive1, (type) => type.isNullable);
+ check(nullType, nonPrimitive2, (type) => type.isNullable);
ruleSet.validateCoverage();
}
@@ -517,9 +517,10 @@
rule(jsIndexable, jsExtendableArray, jsExtendableArray);
rule(jsIndexable, nonPrimitive1, emptyType);
rule(jsIndexable, nonPrimitive2, emptyType);
- rule(jsIndexable, potentialArray, new HType.nonNullSubtype(
- compiler.backend.jsArrayClass, compiler));
- rule(jsIndexable, potentialString, jsString);
+ rule(jsIndexable, potentialArray, new TypeMask.nonNullSubtype(
+ compiler.backend.jsArrayClass));
+ rule(jsIndexable, potentialString, new TypeMask.nonNullSubtype(
+ compiler.backend.jsStringClass));
rule(jsIndexable, jsBooleanOrNull, emptyType);
rule(jsIndexable, jsNumberOrNull, emptyType);
rule(jsIndexable, jsIntegerOrNull, emptyType);
@@ -667,8 +668,8 @@
}
void testRegressions(MockCompiler compiler) {
- HType nonNullPotentialString = new HType.nonNullSubtype(
- patternClass, compiler);
+ TypeMask nonNullPotentialString = new TypeMask.nonNullSubtype(
+ patternClass);
Expect.equals(
potentialString, jsStringOrNull.union(nonNullPotentialString, compiler));
}
@@ -689,66 +690,64 @@
// string types.
patternClass = compiler.coreLibrary.find('Pattern');
- nonPrimitive1 = new HType.nonNullSubtype(
- compiler.mapClass, compiler);
- nonPrimitive2 = new HType.nonNullSubtype(
- compiler.functionClass, compiler);
- potentialArray = new HType.subtype(
- compiler.listClass, compiler);
- potentialString = new HType.subtype(
- patternClass, compiler);
- jsInterceptor = new HType.nonNullSubclass(
- compiler.backend.jsInterceptorClass, compiler);
- jsArrayOrNull = new HType.subclass(
- compiler.backend.jsArrayClass, compiler);
- jsReadableArray = new HType.nonNullSubclass(
- compiler.backend.jsArrayClass, compiler);
- jsMutableArrayOrNull = new HType.subclass(
- compiler.backend.jsMutableArrayClass, compiler);
- jsMutableArray = new HType.nonNullSubclass(
- compiler.backend.jsMutableArrayClass, compiler);
- jsFixedArrayOrNull = new HType.exact(
- compiler.backend.jsFixedArrayClass, compiler);
- jsFixedArray = new HType.nonNullExact(
- compiler.backend.jsFixedArrayClass, compiler);
- jsExtendableArrayOrNull = new HType.exact(
- compiler.backend.jsExtendableArrayClass, compiler);
- jsExtendableArray = new HType.nonNullExact(
- compiler.backend.jsExtendableArrayClass, compiler);
- jsIndexableOrNull = new HType.subtype(
- compiler.backend.jsIndexableClass, compiler);
- jsIndexable = new HType.nonNullSubtype(
- compiler.backend.jsIndexableClass, compiler);
- jsInterceptorOrNull = new HType.subclass(
- compiler.backend.jsInterceptorClass, compiler);
- jsStringOrNull = new HType.exact(
- compiler.backend.jsStringClass, compiler);
- jsString = new HType.nonNullExact(
- compiler.backend.jsStringClass, compiler);
- jsBoolean = new HType.nonNullExact(
- compiler.backend.jsBoolClass, compiler);
- jsNumber = new HType.nonNullSubclass(
- compiler.backend.jsNumberClass, compiler);
- jsInteger = new HType.nonNullExact(
- compiler.backend.jsIntClass, compiler);
- jsDouble = new HType.nonNullExact(
- compiler.backend.jsDoubleClass, compiler);
- jsBooleanOrNull = new HType.exact(
- compiler.backend.jsBoolClass, compiler);
- jsNumberOrNull = new HType.subclass(
- compiler.backend.jsNumberClass, compiler);
- jsIntegerOrNull = new HType.exact(
- compiler.backend.jsIntClass, compiler);
- jsDoubleOrNull = new HType.exact(
- compiler.backend.jsDoubleClass, compiler);
- nullType = new HBoundedType(
- const TypeMask.empty());
- objectType = new HType.nonNullSubclass(
- compiler.objectClass, compiler);
- emptyType = new HBoundedType(
- const TypeMask.nonNullEmpty());
- dynamicType = new HType.subclass(
- compiler.objectClass, compiler);
+ nonPrimitive1 = new TypeMask.nonNullSubtype(
+ compiler.mapClass);
+ nonPrimitive2 = new TypeMask.nonNullSubtype(
+ compiler.functionClass);
+ potentialArray = new TypeMask.subtype(
+ compiler.listClass);
+ potentialString = new TypeMask.subtype(
+ patternClass);
+ jsInterceptor = new TypeMask.nonNullSubclass(
+ compiler.backend.jsInterceptorClass);
+ jsArrayOrNull = new TypeMask.subclass(
+ compiler.backend.jsArrayClass);
+ jsReadableArray = new TypeMask.nonNullSubclass(
+ compiler.backend.jsArrayClass);
+ jsMutableArrayOrNull = new TypeMask.subclass(
+ compiler.backend.jsMutableArrayClass);
+ jsMutableArray = new TypeMask.nonNullSubclass(
+ compiler.backend.jsMutableArrayClass);
+ jsFixedArrayOrNull = new TypeMask.exact(
+ compiler.backend.jsFixedArrayClass);
+ jsFixedArray = new TypeMask.nonNullExact(
+ compiler.backend.jsFixedArrayClass);
+ jsExtendableArrayOrNull = new TypeMask.exact(
+ compiler.backend.jsExtendableArrayClass);
+ jsExtendableArray = new TypeMask.nonNullExact(
+ compiler.backend.jsExtendableArrayClass);
+ jsIndexableOrNull = new TypeMask.subtype(
+ compiler.backend.jsIndexableClass);
+ jsIndexable = new TypeMask.nonNullSubtype(
+ compiler.backend.jsIndexableClass);
+ jsInterceptorOrNull = new TypeMask.subclass(
+ compiler.backend.jsInterceptorClass);
+ jsStringOrNull = new TypeMask.exact(
+ compiler.backend.jsStringClass);
+ jsString = new TypeMask.nonNullExact(
+ compiler.backend.jsStringClass);
+ jsBoolean = new TypeMask.nonNullExact(
+ compiler.backend.jsBoolClass);
+ jsNumber = new TypeMask.nonNullSubclass(
+ compiler.backend.jsNumberClass);
+ jsInteger = new TypeMask.nonNullExact(
+ compiler.backend.jsIntClass);
+ jsDouble = new TypeMask.nonNullExact(
+ compiler.backend.jsDoubleClass);
+ jsBooleanOrNull = new TypeMask.exact(
+ compiler.backend.jsBoolClass);
+ jsNumberOrNull = new TypeMask.subclass(
+ compiler.backend.jsNumberClass);
+ jsIntegerOrNull = new TypeMask.exact(
+ compiler.backend.jsIntClass);
+ jsDoubleOrNull = new TypeMask.exact(
+ compiler.backend.jsDoubleClass);
+ nullType = const TypeMask.empty();
+ objectType = new TypeMask.nonNullSubclass(
+ compiler.objectClass);
+ emptyType = const TypeMask.nonNullEmpty();
+ dynamicType = new TypeMask.subclass(
+ compiler.objectClass);
testUnion(compiler);
testIntersection(compiler);
diff --git a/tests/compiler/dart2js/unneeded_part_js_test.dart b/tests/compiler/dart2js/unneeded_part_js_test.dart
index a4d1835..abbd674 100644
--- a/tests/compiler/dart2js/unneeded_part_js_test.dart
+++ b/tests/compiler/dart2js/unneeded_part_js_test.dart
@@ -40,7 +40,8 @@
diagnosticHandler,
libraryRoot,
packageRoot,
- []);
+ [],
+ {});
asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
Expect.isFalse(compiler.compilationFailed);
}));
diff --git a/tests/compiler/dart2js_extra/mirror_test.dart b/tests/compiler/dart2js_extra/mirror_test.dart
index dbc2b46..5c4e452 100644
--- a/tests/compiler/dart2js_extra/mirror_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_test.dart
@@ -5,9 +5,7 @@
import "package:expect/expect.dart";
import 'dart:mirrors';
-import 'async_helper.dart';
-
-void test(void onDone(bool success)) {
+void main() {
var now = new DateTime.now();
InstanceMirror mirror = reflect(now);
print('now: ${now}');
@@ -18,15 +16,4 @@
print('mirror.invoke("toUtc", []): $value');
Expect.isTrue(value.hasReflectee);
Expect.equals(now.toUtc(), value.reflectee);
-
- mirror.invokeAsync(const Symbol("toUtc"), []).then((value) {
- print('mirror.invokeAsync("toUtc", []): $value');
- Expect.isTrue(value.hasReflectee);
- Expect.equals(now.toUtc(), value.reflectee);
- onDone(true);
- });
-}
-
-void main() {
- asyncTest(test);
}
diff --git a/tests/corelib/bool_from_environment_default_value_test.dart b/tests/corelib/bool_from_environment_default_value_test.dart
index 82acf265..f412522 100644
--- a/tests/corelib/bool_from_environment_default_value_test.dart
+++ b/tests/corelib/bool_from_environment_default_value_test.dart
@@ -5,7 +5,7 @@
import "package:expect/expect.dart";
main() {
- Expect.isNull(const bool.fromEnvironment('NOT_FOUND'));
+ Expect.isFalse(const bool.fromEnvironment('NOT_FOUND'));
Expect.isTrue(const bool.fromEnvironment('NOT_FOUND', defaultValue: true));
Expect.isFalse(const bool.fromEnvironment('NOT_FOUND', defaultValue: false));
Expect.isNull(const bool.fromEnvironment('NOT_FOUND', defaultValue: null));
diff --git a/tests/corelib/bool_from_environment_test.dart b/tests/corelib/bool_from_environment_test.dart
index 66351e4..34e9ee1 100644
--- a/tests/corelib/bool_from_environment_test.dart
+++ b/tests/corelib/bool_from_environment_test.dart
@@ -1,11 +1,14 @@
// 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.
-// SharedOptions=-Da=true -Db=false
+// SharedOptions=-Da=true -Db=false -Dc=NOTBOOL -Dd=True
import "package:expect/expect.dart";
main() {
Expect.isTrue(const bool.fromEnvironment('a'));
Expect.isFalse(const bool.fromEnvironment('b'));
+ Expect.isTrue(const bool.fromEnvironment('c', defaultValue: true));
+ Expect.isFalse(const bool.fromEnvironment('c', defaultValue: false));
+ Expect.isFalse(const bool.fromEnvironment('d', defaultValue: false));
}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 8a46c88..90f4ff8 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -2,8 +2,7 @@
# 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.
-# Skip these tests until XXX.fromEnvironment in dart2js lands.
-[ $compiler == dart2js || $compiler == dart2dart]
+[ $compiler == dart2dart]
bool_from_environment2_test: Skip
bool_from_environment_default_value_test: Skip
bool_from_environment_test: Skip
diff --git a/tests/corelib/int_from_environment2_test.dart b/tests/corelib/int_from_environment2_test.dart
index 8b14526..2645337 100644
--- a/tests/corelib/int_from_environment2_test.dart
+++ b/tests/corelib/int_from_environment2_test.dart
@@ -1,7 +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.
-// SharedOptions=-Da=x -Db=- -Dc=0xg
+// SharedOptions=-Da=x -Db=- -Dc=0xg -Dd=+ -Dd=
import "package:expect/expect.dart";
@@ -9,4 +9,7 @@
Expect.isNull(const int.fromEnvironment('a'));
Expect.isNull(const int.fromEnvironment('b'));
Expect.isNull(const int.fromEnvironment('c'));
+ Expect.isNull(const int.fromEnvironment('d'));
+ Expect.isNull(const int.fromEnvironment('e'));
}
+
diff --git a/tests/corelib/int_from_environment_default_value_test.dart b/tests/corelib/int_from_environment_default_value_test.dart
index bb318d0..d97145a 100644
--- a/tests/corelib/int_from_environment_default_value_test.dart
+++ b/tests/corelib/int_from_environment_default_value_test.dart
@@ -6,5 +6,6 @@
main() {
Expect.isNull(const int.fromEnvironment('NOT_FOUND'));
- Expect.equals(12345, const int.fromEnvironment('NOT_FOUND', defaultValue: 12345));
+ Expect.equals(12345, const int.fromEnvironment('NOT_FOUND',
+ defaultValue: 12345));
}
diff --git a/tests/corelib/int_from_environment_test.dart b/tests/corelib/int_from_environment_test.dart
index f842fdd..f6033a5 100644
--- a/tests/corelib/int_from_environment_test.dart
+++ b/tests/corelib/int_from_environment_test.dart
@@ -1,7 +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.
-// SharedOptions=-Da=1 -Db=-12 -Dc=0x123 -Dd=-0x1234
+// SharedOptions=-Da=1 -Db=-12 -Dc=0x123 -Dd=-0x1234 -De=+0x112296 -Df=99999999999999999999
import "package:expect/expect.dart";
@@ -10,4 +10,6 @@
Expect.equals(-12, const int.fromEnvironment('b'));
Expect.equals(0x123, const int.fromEnvironment('c'));
Expect.equals(-0x1234, const int.fromEnvironment('d'));
+ Expect.equals(0x112296, const int.fromEnvironment('e'));
+ Expect.equals(99999999999999999999, const int.fromEnvironment('f'));
}
diff --git a/tests/html/custom/template_wrappers_test.dart b/tests/html/custom/template_wrappers_test.dart
index 8754f85..c52ad7b 100644
--- a/tests/html/custom/template_wrappers_test.dart
+++ b/tests/html/custom/template_wrappers_test.dart
@@ -32,7 +32,6 @@
main() {
useHtmlConfiguration();
- var registeredTypes = false;
setUp(loadPolyfills);
test('element is upgraded once', () {
@@ -52,12 +51,31 @@
expect(createdCount, 1);
});
});
+/*
+ test('old wrappers do not cause multiple upgrades', () {
+ createdCount = 0;
+ var d1 = document.querySelector('x-custom-two');
+ d1.attributes['foo'] = 'bar';
+ d1 = null;
+
+ document.register('x-custom-two', CustomElement);
+
+ expect(createdCount, 1);
+
+ forceGC();
+
+ return new Future.delayed(new Duration(milliseconds: 50)).then((_) {
+ var d = document.querySelector('x-custom-two');
+ expect(createdCount, 1);
+ });
+ });
+*/
}
void forceGC() {
var N = 1000000;
- var M = 1000;
+ var M = 100;
for (var i = 0; i < M; ++i) {
var l = new List(N);
}
diff --git a/tests/html/custom/template_wrappers_test.html b/tests/html/custom/template_wrappers_test.html
index ea5b81d..2613bdc 100644
--- a/tests/html/custom/template_wrappers_test.html
+++ b/tests/html/custom/template_wrappers_test.html
@@ -16,6 +16,7 @@
<template class='t1'>
<x-custom></x-custom>
</template>
+ <x-custom-two></x-custom-two>
<script type="text/javascript"
src="/packages/unittest/test_controller.js"></script>
%TEST_SCRIPTS%
diff --git a/tests/isolate/illegal_msg_test.dart b/tests/isolate/illegal_msg_function_test.dart
similarity index 87%
rename from tests/isolate/illegal_msg_test.dart
rename to tests/isolate/illegal_msg_function_test.dart
index 422ae39..f967afd 100644
--- a/tests/isolate/illegal_msg_test.dart
+++ b/tests/isolate/illegal_msg_function_test.dart
@@ -2,9 +2,11 @@
// 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 illegal_msg_tests;
+library illegal_msg_function_test;
+
import "package:expect/expect.dart";
-import 'dart:isolate';
+import "dart:isolate";
+import "dart:async" show Future;
import "package:async_helper/async_helper.dart";
funcFoo(x) => x + 2;
@@ -18,6 +20,8 @@
}
main() {
+ var function = funcFoo;
+
ReceivePort port = new ReceivePort();
Future spawn = Isolate.spawn(echo, port.sendPort);
var caught_exception = false;
@@ -25,7 +29,7 @@
asyncStart();
stream.first.then((snd) {
try {
- snd.send(funcFoo);
+ snd.send(function);
} catch (e) {
caught_exception = true;
}
diff --git a/tests/isolate/illegal_msg_test.dart b/tests/isolate/illegal_msg_mirror_test.dart
similarity index 75%
copy from tests/isolate/illegal_msg_test.dart
copy to tests/isolate/illegal_msg_mirror_test.dart
index 422ae39..eed2981 100644
--- a/tests/isolate/illegal_msg_test.dart
+++ b/tests/isolate/illegal_msg_mirror_test.dart
@@ -1,13 +1,18 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// 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 illegal_msg_tests;
-import "package:expect/expect.dart";
-import 'dart:isolate';
-import "package:async_helper/async_helper.dart";
+library illegal_msg_mirror_test;
-funcFoo(x) => x + 2;
+import "package:expect/expect.dart";
+import "dart:isolate";
+import "dart:async" show Future;
+import "package:async_helper/async_helper.dart";
+import "dart:mirrors";
+
+class Class {
+ method() {}
+}
echo(sendPort) {
var port = new ReceivePort();
@@ -18,6 +23,8 @@
}
main() {
+ var methodMirror = reflectClass(Class).declarations[#method];
+
ReceivePort port = new ReceivePort();
Future spawn = Isolate.spawn(echo, port.sendPort);
var caught_exception = false;
@@ -25,7 +32,7 @@
asyncStart();
stream.first.then((snd) {
try {
- snd.send(funcFoo);
+ snd.send(methodMirror);
} catch (e) {
caught_exception = true;
}
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 2fb39ff..fa6c738 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -62,7 +62,8 @@
serialization_test: Pass # Issue 12628
isolate_import_negative_test: Fail # Issue 12628
isolate2_negative_test: Fail # Issue 12628
-illegal_msg_test: Pass # Issue 12628
+illegal_msg_function_test: Pass # Issue 12628
+illegal_msg_mirror_test: Pass # Issue 12628
[ $compiler == dart2js && $runtime == chromeOnAndroid ]
isolate_stress_test: Pass, Slow # TODO(kasperl): Please triage.
@@ -102,7 +103,8 @@
cross_isolate_message_test: Fail
global_error_handler2_test: Fail
global_error_handler_test: Fail
-illegal_msg_test: Fail
+illegal_msg_function_test: Fail
+illegal_msg_mirror_test: Fail
isolate_complex_messages_test: Fail
isolate_stress_test: Fail
mandel_isolate_test: Fail
@@ -119,9 +121,7 @@
[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
browser/typed_data_message_test: StaticWarning
-illegal_msg_test: StaticWarning
isolate3_negative_test: CompileTimeError
-isolate/illegal_msg_test: StaticWarning
isolate_import_negative_test: CompileTimeError
isolate/mint_maker_test: StaticWarning
isolate/unresolved_ports_test: StaticWarning
diff --git a/tests/language/cast2_test.dart b/tests/language/cast2_test.dart
index 397ac45..d67c89b 100644
--- a/tests/language/cast2_test.dart
+++ b/tests/language/cast2_test.dart
@@ -3,10 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
// Dart test program for constructors and initializers.
+import "package:expect/expect.dart";
+
// Test 'expression as Type' casts.
class C {
final int foo = 42;
+
+ int val = 0;
+ void inc() { ++val; }
}
class D extends C {
@@ -14,10 +19,14 @@
}
main() {
- Object oc = new C();
- Object od = new D();
+ C oc = new C();
+ D od = new D();
(oc as dynamic).bar; /// 01: runtime error
+
+ // Casts should always evaluate the left-hand side, if only for its effects.
+ oc.inc() as dynamic;
+ Expect.equals(1, oc.val);
+ oc.inc() as Object;
+ Expect.equals(2, oc.val);
}
-
-
diff --git a/tests/language/implicit_setter_test.dart b/tests/language/implicit_setter_test.dart
deleted file mode 100644
index ff940bf..0000000
--- a/tests/language/implicit_setter_test.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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.
-
-import "package:expect/expect.dart";
-
-// Test of final fields generating implicit setters that throw.
-
-String x = "toplevel"; // Should never be read in this test.
-
-class B {
- var x = 37;
-}
-
-class C extends B {
- final x = 42;
-
- // Local access should work the same as direct access.
- get cx => x;
- void set cx(value) {
- x = value; /// 02: static type warning
- erase(this).x = value; // but crash even if the direct setting is omitted.
- }
-
- // Super access should work.
- get bx => super.x;
- void set bx(value) { super.x = value; }
-
- noSuchMethod(i) => "noSuchMethod"; // Should never be called in this test.
-}
-
-// Class with only final field has setter in implicit interface.
-class A {
- final int x = 42;
-}
-
-// Should get warning because the implicit interface contains the setter,
-// and this non-abstract class doesn't.
-class AI
- implements A /// 01: static type warning
-{
- int get x => 37;
-}
-
-// Erases static type information. Used to avoid *static* warnings when
-// using a setter for a final field.
-erase(x) => x;
-
-void main() {
- Expect.equals(42, new C().x);
- Expect.throws(() { erase(new C()).x = 10; });
- Expect.equals(42, new C().cx);
- Expect.throws(() { erase(new C()).cx = 10; });
- Expect.equals(37, new C().bx);
- Expect.equals(10, (erase(new C())..bx = 10).bx);
-
- Expect.equals(42, new A().x);
- Expect.throws(() { erase(new A()).x = 10; });
- Expect.equals(37, new AI().x);
- Expect.throws(() { erase(new AI()).x = 10; });
-
- Expect.equals("toplevel", x); // Should not have changed.
-}
diff --git a/tests/language/language.status b/tests/language/language.status
index 79ab9b5..9c6fe8b 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -22,7 +22,6 @@
lazy_static3_test: Fail # Issue 12593
duplicate_export_negative_test: Fail # Issue 6134
mixin_forwarding_constructor2_test: Fail # Issue 13641
-implicit_setter_test: Fail # Issue 13917
[ $compiler == none && $runtime == vm ]
class_keyword_test/02: MissingCompileTimeError # Issue 13627
@@ -75,9 +74,8 @@
[ $compiler == none && $runtime == dartium ]
first_class_types_literals_test: Pass, Fail # Issue 13719: Please triage this failure.
-issue13474_test: Pass, Fail # Issue 13719: Please triage this failure.
-regress_13494_test: Pass, Fail # Issue 13719: Please triage this failure.
+issue13474_test: Pass, Fail # Issue 14651.
[ $compiler == none && ( $runtime == dartium || $runtime == drt ) ]
typed_message_test: Crash, Fail # Issue 13921, 14400
-
+vm/optimized_guarded_field_isolates_test: Fail # Issue 13921.
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 96b17d3..bf10504 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -23,7 +23,6 @@
built_in_identifier_test/none: Fail # Issue 13023
-
# Please add new failing tests before this line.
# Section below is for invalid tests.
#
@@ -161,10 +160,6 @@
# test issue 14363, "if ((a is B))" has the same effect as "if (a is B)", so no static warning expected
type_promotion_parameter_test/53: Fail
-# test issue 14406, setter for final field was removed from spec
-implicit_setter_test/01: fail
-implicit_setter_test/02: fail
-
# test issue 14410, "typedef C = " is now really illegal syntax
mixin_illegal_syntax_test/none: fail
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index a8ebdfd..4a6e5a3 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -23,7 +23,6 @@
built_in_identifier_test/none: Fail # Issue 13023
-
# Please add new failing tests before this line.
# Section below is for invalid tests.
#
@@ -174,10 +173,6 @@
type_promotion_more_specific_test/10: Fail
type_promotion_more_specific_test/11: Fail
-# test issue 14406, setter for final field was removed from spec
-implicit_setter_test/01: fail
-implicit_setter_test/02: fail
-
# test issue 14410, "typedef C = " is now really illegal syntax
mixin_illegal_syntax_test/none: fail
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 426c6c4..6ffdd63 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -23,7 +23,6 @@
type_variable_conflict_test/04: Fail # Issue 13702
type_variable_conflict_test/05: Fail # Issue 13702
type_variable_conflict_test/06: Fail # Issue 13702
-implicit_setter_test: Fail # Issue 13919
# VM specific tests that should not be run by dart2js.
vm/*: Skip # Issue 12699
@@ -118,6 +117,7 @@
not_enough_positional_arguments_test/02: CompileTimeError # Issue 12838
not_enough_positional_arguments_test/05: CompileTimeError # Issue 12838
metadata_test: CompileTimeError # Issue 5841
+metadata_syntax_test/05: MissingCompileTimeError # Issue 14548
infinity_test: RuntimeError # Issue 4984
positive_bit_operations_test: RuntimeError # Issue 12795
mixin_mixin2_test: RuntimeError # Issue 13109.
@@ -136,7 +136,6 @@
built_in_identifier_test/01: CompileTimeError # Issue 13022
scope_variable_test/01: MissingCompileTimeError # Issue 13016
-static_final_field2_test/02: MissingCompileTimeError # Issue 13017
numbers_test: RuntimeError, OK # Issue 1533
canonical_const2_test: RuntimeError, OK # Issue 1533
@@ -227,6 +226,7 @@
not_enough_positional_arguments_test/05: Fail # Issue 12839
metadata_test: Fail # Issue 12762
+metadata_syntax_test/05: MissingCompileTimeError # Issue 14548
const_var_test: Pass, Fail # Issue 12794
map_literal3_test: Fail # Issue 12794
external_test/13: Fail # Issue 12888
@@ -236,7 +236,6 @@
map_literal1_test/01: Fail # Issue 12993
method_override4_test: Fail # Issue 12810
method_override5_test: Fail # Issue 12810
-static_final_field2_test/02: Fail # Issue 13017
scope_variable_test/01: Fail # Issue 13016
factory_redirection_test/01: Fail # Issue 12753
factory_redirection_test/02: Crash # Issue 12753
diff --git a/tests/language/metadata_syntax_test.dart b/tests/language/metadata_syntax_test.dart
deleted file mode 100644
index dc3ff8c..0000000
--- a/tests/language/metadata_syntax_test.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-import "package:expect/expect.dart";
-
-// Test that is is an error to use type arguments in metadata without
-// parens.
-
-@Bar()
-@List<String> /// 01: compile-time error
-class Bar {
- @Bar()
- @List<String> /// 02: compile-time error
- const Bar();
-
- @Bar()
- @List<String> /// 03: compile-time error
- final x = '';
-}
-
-main() {
- Expect.equals('', new Bar().x);
- Expect.equals('', const Bar().x);
-}
diff --git a/tests/language/range_analysis2_test.dart b/tests/language/range_analysis2_test.dart
new file mode 100644
index 0000000..a84ede69
--- /dev/null
+++ b/tests/language/range_analysis2_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+// Regression test for dart2js that used to remove bounds checks on
+// boxed variables.
+
+import "package:expect/expect.dart";
+
+main() {
+ var a = 0;
+ var b = [1];
+ foo() => b[a--] + b[a];
+ Expect.throws(foo, (e) => e is RangeError);
+}
diff --git a/tests/language/static_final_field2_test.dart b/tests/language/static_final_field2_test.dart
index c80588a..2c550a3 100644
--- a/tests/language/static_final_field2_test.dart
+++ b/tests/language/static_final_field2_test.dart
@@ -12,10 +12,11 @@
final n;
static const a; /// 02: compile-time error
static const b = 3 + 5;
- static const c; /// 02: continued
}
main() {
A.x = 2; /// 01: static type warning, runtime error
new B();
+ print(B.b);
+ print(B.a); /// 02: continued
}
diff --git a/tests/language/substring_test.dart b/tests/language/substring_test.dart
new file mode 100644
index 0000000..aee5777
--- /dev/null
+++ b/tests/language/substring_test.dart
@@ -0,0 +1,18 @@
+// 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 version of two-argument Ackermann-Peter function.
+
+import "package:expect/expect.dart";
+
+
+main() {
+ try {
+ print("abcdef".substring(1.5, 3.5)); /// 01: static type warning
+ Expect.fail("Should have thrown an exception"); /// 01: continued
+ } on TypeError catch (e) {
+ // OK.
+ } on ArgumentError catch (e) {
+ // OK.
+ }
+}
diff --git a/tests/language/type_check_test.dart b/tests/language/type_check_test.dart
new file mode 100644
index 0000000..0b10a72
--- /dev/null
+++ b/tests/language/type_check_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// Regression test for dart2js that used to remove the a B type check
+// after an A type check, because it thought any subtype of A had to be B.
+
+import "package:expect/expect.dart";
+
+class A {
+}
+
+class B extends A {
+}
+
+main() {
+ var a = [new A(), new B()];
+ var b = a[0];
+ b = b as A;
+ Expect.throws(() => b as B, (e) => e is CastError);
+}
diff --git a/tests/language/type_propagation3_test.dart b/tests/language/type_propagation3_test.dart
new file mode 100644
index 0000000..e17e95e
--- /dev/null
+++ b/tests/language/type_propagation3_test.dart
@@ -0,0 +1,56 @@
+// 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.
+
+// Regression test for dart2js that used to generate wrong code for
+// it. The bug happened in the SSA type propagation.
+
+class A {
+ next() => new B();
+ doIt() => null;
+ bool get isEmpty => false;
+ foo() => 42;
+ bar() => 54;
+}
+
+bool entered = false;
+
+class B extends A {
+ foo() => 54;
+ doIt() => new A();
+ bool get isEmpty => true;
+ bar() => entered = true;
+}
+
+// (1) At initialization phase of the type propagation, [a] would be
+// marked as [exact A].
+// (2) Will make the loop phi [b] typed [null, exact A].
+// (3) Will create a [HTypeKnown] [exact A] for [b].
+// (4) Will create a [HTypeKnown] [exact A] for [b] and update users
+// of [b] to use this [HTypeKnown] instead.
+// (5) [a] will be updated to [subclass A].
+// (6) Will change the [HTypeKnown] of [b] from [exact A] to [subclass A].
+// (7) Receiver is [subclass A] and it will refine it to
+// [subclass A]. We used to wrongly assume there was
+// no need to update the [HTypeKnown] created in (3).
+// (8) Consider that bar is called on an [exact A] (the [HTypeKnown]
+// created in (3)) and remove the call because it does not have
+// any side effects.
+
+main() {
+ var a = new A();
+ for (var i in [42]) {
+ a = a.next();
+ }
+
+ // (1, 5)
+
+ var b = a;
+ while (b.isEmpty) { // (4, 6)
+ b.foo(); // (3, 7)
+ b.bar(); // (8)
+ b = b.doIt(); // (2)
+ }
+
+ if (!entered) throw 'Test failed';
+}
diff --git a/tests/language/vm/optimized_guarded_field_isolates_test.dart b/tests/language/vm/optimized_guarded_field_isolates_test.dart
new file mode 100644
index 0000000..fc5e915
--- /dev/null
+++ b/tests/language/vm/optimized_guarded_field_isolates_test.dart
@@ -0,0 +1,70 @@
+// 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=--optimization_counter_threshold=100
+
+// Test field type tracking and field list-length tracking in the presence of
+// multiple isolates.
+
+import "dart:isolate";
+import "dart:async";
+import "package:expect/expect.dart";
+
+class A {
+ A(this.a);
+ var a;
+}
+
+class B extends A {
+ B(a, this.b) : super(a) { }
+
+ var b;
+}
+
+f1(SendPort send_port) {
+ send_port.send(new B("foo", "bar"));
+}
+
+test_b(B obj) => obj.a + obj.b;
+
+test_field_type() {
+ var receive_port = new ReceivePort();
+ Future<Isolate> isolate = Isolate.spawn(f1, receive_port.sendPort);
+ B b = new B(1, 2);
+ for (var i = 0; i < 200; i++) { test_b(b); }
+ Expect.equals(3, test_b(b));
+ Future<B> item = receive_port.first;
+ item.then((B value) {
+ Expect.equals("foobar", test_b(value));
+ receive_port.close();
+ });
+}
+
+class C {
+ C(this.list);
+ final List list;
+}
+
+f2(SendPort send_port) {
+ send_port.send(new C(new List(1)));
+}
+
+test_c(C obj) => obj.list[9999];
+
+test_list_length() {
+ var receive_port = new ReceivePort();
+ Future<Isolate> isolate = Isolate.spawn(f2, receive_port.sendPort);
+ C c = new C(new List(10000));
+ for (var i = 0; i < 200; i++) { test_c(c); }
+ Expect.equals(null, test_c(c));
+ Future<C> item = receive_port.first;
+ item.then((C value) {
+ Expect.throws(() => test_c(value), (e) => e is RangeError);
+ receive_port.close();
+ });
+}
+
+main() {
+ test_field_type();
+ test_list_length();
+}
diff --git a/tests/language/vm/optimized_guarded_field_test.dart b/tests/language/vm/optimized_guarded_field_test.dart
index 2ef5dcb..c6aea4d 100644
--- a/tests/language/vm/optimized_guarded_field_test.dart
+++ b/tests/language/vm/optimized_guarded_field_test.dart
@@ -17,6 +17,41 @@
test(obj) => obj.foo == null ? "null" : "other";
+
+class C {
+ C(this.x, this.y);
+ final x;
+ final y;
+}
+
+test_deopt(a, b) {
+ var c = new C(a, b);
+ return c.x + c.y;
+}
+
+
+create_error (x) {
+ return x as int;
+}
+
+check_stacktrace(e) {
+ var s = e.stackTrace;
+ if (identical(s, null)) throw "FAIL";
+ // s should never be null.
+ return "OK";
+}
+
+test_stacktrace() {
+ try {
+ create_error("bar");
+ } catch (e) {
+ Expect.equals("OK", check_stacktrace(e));
+ for (var i=0; i<20; i++) { check_stacktrace(e); }
+ Expect.equals("OK", check_stacktrace(e));
+ }
+}
+
+
main() {
var a = new A();
var b = new B();
@@ -32,4 +67,13 @@
a.foo = 123;
Expect.equals("other", test(a));
Expect.equals("null", test(b));
+
+ // Test guarded fields with allocation sinking and deoptimization.
+ Expect.equals(43, test_deopt(42, 1));
+ for (var i = 0; i < 20; i++) { test_deopt(42, 1); }
+ Expect.equals(43, test_deopt(42, 1));
+ Expect.equals("aaabbb", test_deopt("aaa", "bbb"));
+
+ // Regression test for fields initialized in native code (Error._stackTrace).
+ test_stacktrace();
}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index bba8036..8244ded 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -16,25 +16,21 @@
mirrors/basic_types_in_dart_core_test: RuntimeError # Issue 14025
mirrors/class_declarations_test/none: RuntimeError # Issue 13440
mirrors/closures_test/none: RuntimeError # Issue 6490
-mirrors/closure_mirror_find_in_context_test: Fail # Issue 6490
mirrors/constructor_kinds_test: RuntimeError # Issue 13799
mirrors/equality_test/02: RuntimeError # Issue 12333
mirrors/fake_function_with_call_test: RuntimeError # Issue 11612
mirrors/fake_function_without_call_test: RuntimeError # Issue 11612
+mirrors/find_in_context_test: Fail # Issue 6490
+mirrors/find_in_context_private_test: Fail # Issue 6490
mirrors/find_in_context_fake_function_test: Fail # Issue 6490
mirrors/function_type_mirror_test: RuntimeError # Issue 12166
mirrors/generics_test/01: RuntimeError # Issue 12087
-mirrors/generic_bounded_test/none: RuntimeError # Issue 12087
-mirrors/generic_bounded_test/01: RuntimeError # Issue 12087
-mirrors/generic_bounded_by_type_parameter_test/none: RuntimeError # Issue 12087
-mirrors/generic_bounded_by_type_parameter_test/01: RuntimeError # Issue 12087
-mirrors/generic_f_bounded_test/01: RuntimeError # Issue 12087
mirrors/generic_f_bounded_mixin_application_test: RuntimeError # Issue 12087
mirrors/generic_function_typedef_test: RuntimeError # Issue 12333
mirrors/generic_interface_test: RuntimeError # Issue 12087
mirrors/generic_mixin_test: RuntimeError # Issue 12333
mirrors/generic_mixin_applications_test: RuntimeError # Issue 12333
-mirrors/generics_substitution_test: RuntimeError # Issue 12087
+mirrors/generics_substitution_test/01: RuntimeError # Issue 12087
mirrors/hierarchy_invariants_test: RuntimeError # Issue 11863
mirrors/immutable_collections_test: RuntimeError # Issue 14030
mirrors/initializing_formals_test/01: RuntimeError # Issue 6490
@@ -53,6 +49,12 @@
mirrors/library_declarations_test/none: RuntimeError # Issue 13439, Issue 13733
mirrors/library_metadata2_test/01: CompileTimeError # Issue 13633
mirrors/library_uri_io_test: Skip # Not intended for dart2js as it uses dart:io.
+mirrors/metadata_allowed_values_test/01: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/05: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/10: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/11: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/13: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/14: MissingCompileTimeError # Issue 14548
mirrors/method_mirror_name_test: RuntimeError # Issue 6335
mirrors/method_mirror_properties_test: RuntimeError # Issue 11861
mirrors/method_mirror_returntype_test : RuntimeError # Issue 11928
@@ -70,6 +72,7 @@
mirrors/redirecting_factory_test/02: RuntimeError # Issue 6490
mirrors/reflected_type_test: RuntimeError # Issue 12607
mirrors/static_members_test: CompileTimeError # Issue 14633, Issue 12164
+mirrors/set_field_with_final_inheritance_test: RuntimeError # Issue 13919
mirrors/symbol_validation_test: RuntimeError # Issue 13597
mirrors/toplevel_members_test: CompileTimeError # Issue 14633, Issue 12164
mirrors/type_argument_is_type_variable_test: RuntimeError # Issue 12333
@@ -79,10 +82,6 @@
mirrors/type_variable_owner_test/01: RuntimeError # Issue 12785
mirrors/generic_type_mirror_test/01: RuntimeError # 6490
-[ $compiler == dart2js && $unchecked ]
-mirrors/generic_bounded_test/02: RuntimeError # Issue 12087
-mirrors/generic_bounded_by_type_parameter_test/02: RuntimeError # Issue 12087
-
[ $runtime == safari ]
mirrors/return_type_test: Pass, Timeout # Issue 12858
@@ -183,6 +182,9 @@
mirrors/typedef_test/01: Fail, OK # Incorrect dart2js behavior.
mirrors/generic_f_bounded_test/01: RuntimeError # Issue 14000
+mirrors/generic_superclass_test/01: RuntimeError # Issue 14000
+mirrors/generic_type_mirror_test/02: RuntimeError # Issue 14613
+
mirrors/symbol_validation_test: RuntimeError # Issue 13596
mirrors/static_members_test: RuntimeError # Issue 14632
@@ -194,10 +196,10 @@
async/timer_not_available_test: SkipByDesign # only meant to test when there is no way to implement timer (currently only in d8)
[ $compiler == none && ( $runtime == drt || $runtime == dartium ) ]
+async/schedule_microtask6_test: Fail # Issue 10910
mirrors/immutable_collections_test: Fail # Issue 11857, Issue 14321
mirrors/library_uri_io_test: Skip # Not intended for drt as it uses dart:io.
mirrors/local_isolate_test: Skip # http://dartbug.com/12188
-async/schedule_microtask6_test: Fail # Issue 10910
[ $compiler == none && $runtime == drt && $mode == debug ]
mirrors/hierarchy_invariants_test: Pass, Slow # Issue 14449
@@ -209,7 +211,6 @@
[ $arch == simmips || $arch == mips ]
convert/chunked_conversion_utf88_test: Pass, Slow # Issue 12025.
convert/streamed_conversion_json_utf8_decode_test: Pass, Slow
-typed_data/uint32x4_list_test: Pass, Crash # Issue 14644
[ $arch == simarm ]
convert/chunked_conversion_utf88_test: Pass, Slow # Issue 12644.
@@ -218,6 +219,9 @@
[ $compiler == none && $runtime == dartium ]
async/schedule_microtask5_test: Pass, Timeout # Issue 13719: Please triage this failure.
async/timer_cancel2_test: Pass, Timeout # Issue 13719: Please triage this failure.
+mirrors/find_in_context_test: Fail # Issue 13719: Needs VM flag
+mirrors/find_in_context_private_test: Fail # Issue 13719: Needs VM flag
+mirrors/find_in_context_fake_function_test: Fail # Issue 13719: Needs VM flag
[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
# Issue 13921: spawnFunction is not allowed on Dartium's DOM thread.
@@ -249,6 +253,7 @@
mirrors/equality_test/02: StaticWarning # Issue 14524
mirrors/generic_f_bounded_mixin_application_test: CompileTimeError # Issue 14116
mirrors/invoke_named_test: StaticWarning # Issue 14522
+mirrors/metadata_allowed_values_test/none: CompileTimeError # Issue 14688
mirrors/private_symbol_test: StaticWarning # Issue 14524
mirrors/reflect_class_test: StaticWarning # Issue 14524
mirrors/type_variable_owner_test: StaticWarning # Issue 14524
@@ -262,7 +267,7 @@
mirrors/find_in_context_fake_function_test: StaticWarning, OK # Implements Function without defining call.
mirrors/immutable_collections_test: StaticWarning, OK # Expect failure for any type of Iterable.
mirrors/inference_and_no_such_method_test: StaticWarning, OK # Expect to trigger noSuchMethod.
-mirrors/library_metadata2_test/01: StaticWarning, OK # Compile-time or run-time
+mirrors/library_metadata2_test/01: CompileTimeError # Test issue 14682
mirrors/basic_types_in_dart_core_test: StaticWarning, OK # API being removed.
mirrors/constructor_kinds_test/01: StaticWarning, OK # API being removed.
@@ -273,6 +278,7 @@
mirrors/fake_function_with_call_test: StaticWarning, OK # API being removed.
mirrors/generic_function_typedef_test: StaticWarning, OK # API being removed.
mirrors/generic_type_mirror_test/01: StaticWarning, OK # API being removed.
+mirrors/generic_type_mirror_test/02: StaticWarning, OK # API being removed.
mirrors/generic_type_mirror_test/none: StaticWarning, OK # API being removed.
mirrors/generics_substitution_test: StaticWarning, OK # API being removed.
mirrors/inherit_field_test: StaticWarning, OK # API being removed.
@@ -282,8 +288,6 @@
mirrors/initializing_formals_test/none: StaticWarning, OK # API being removed.
mirrors/intercepted_class_test: StaticWarning, OK # API being removed.
mirrors/intercepted_object_test: StaticWarning, OK # API being removed.
-mirrors/invoke_closurization_test: StaticWarning, OK # API being removed.
-mirrors/invoke_test: StaticWarning, OK # API being removed.
mirrors/lazy_static_test: StaticWarning, OK # API being removed.
mirrors/libraries_test: StaticWarning, OK # API being removed.
mirrors/library_metadata_test: StaticWarning, OK # API being removed.
diff --git a/tests/lib/mirrors/find_in_context_fake_function_test.dart b/tests/lib/mirrors/find_in_context_fake_function_test.dart
index 5ccfaee..93aeeb8 100644
--- a/tests/lib/mirrors/find_in_context_fake_function_test.dart
+++ b/tests/lib/mirrors/find_in_context_fake_function_test.dart
@@ -2,6 +2,8 @@
// 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=--support_find_in_context=true
+
// Regression test: this used to crash the VM.
library test.find_in_context_fake_function;
diff --git a/tests/lib/mirrors/find_in_context_private_test.dart b/tests/lib/mirrors/find_in_context_private_test.dart
new file mode 100644
index 0000000..dc35893
--- /dev/null
+++ b/tests/lib/mirrors/find_in_context_private_test.dart
@@ -0,0 +1,104 @@
+// 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=--support_find_in_context=true
+
+library test.find_in_context_private;
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+var _globalVariable = "globalVariable";
+_globalFoo() => 17;
+
+class S {
+ static _staticFooInS() => "staticFooInS";
+ static var _staticInS = "staticInS";
+ var _instanceInS = "instanceInS";
+}
+
+class C extends S {
+ static _staticFooInC() => "staticFooInC";
+ static var _staticInC = "staticInC";
+ var _instanceInC = "instanceInC";
+
+ _method() {
+ var _local = "local";
+ nested() {
+ var _innerLocal = "innerLocal";
+ print(this._instanceInC);
+ print(_local);
+ print(_innerLocal);
+ }
+ return nested;
+ }
+
+}
+
+doFindInContext(cm, name, value) {
+ Expect.equals(value,
+ cm.findInContext(name).reflectee);
+}
+dontFindInContext(cm, name) {
+ Expect.isNull(cm.findInContext(name));
+}
+
+main() {
+ LibraryMirror wrongLibrary = reflectClass(List).owner;
+ p(name) => MirrorSystem.getSymbol(name, wrongLibrary);
+
+ C c = new C();
+
+ // In the context of C._method.nested.
+ ClosureMirror cm = reflect(c._method());
+
+ // N.B.: innerLocal is only defined with respective to an activation of the
+ // closure 'nested', not the closure itself.
+ dontFindInContext(cm, #_innerLocal);
+
+ doFindInContext(cm, #_local, "local");
+ doFindInContext(cm, #_method, c._method);
+ doFindInContext(cm, #_instanceInC, "instanceInC");
+ doFindInContext(cm, #_staticInC, "staticInC");
+ doFindInContext(cm, #_staticFooInC, C._staticFooInC);
+ dontFindInContext(cm, #_staticInS);
+ dontFindInContext(cm, #_staticFooInS);
+ doFindInContext(cm, #_globalFoo, _globalFoo);
+ doFindInContext(cm, #_globalVariable, "globalVariable");
+
+ dontFindInContext(cm, p('_local'));
+ dontFindInContext(cm, p('_innerLocal'));
+ dontFindInContext(cm, p('_method'));
+ dontFindInContext(cm, p('_instanceInC'));
+ dontFindInContext(cm, p('_staticInC'));
+ dontFindInContext(cm, p('_staticFooInC'));
+ dontFindInContext(cm, p('_staticInS'));
+ dontFindInContext(cm, p('_staticFooInS'));
+ dontFindInContext(cm, p('_globalFoo'));
+ dontFindInContext(cm, p('_globalVariable'));
+
+ // In the context of C._method.
+ cm = reflect(c._method);
+ dontFindInContext(cm, #_innerLocal);
+ dontFindInContext(cm, #_local); // N.B.: See above.
+ doFindInContext(cm, #_method, c._method);
+ doFindInContext(cm, #_instanceInC, "instanceInC");
+ doFindInContext(cm, #_staticInC, "staticInC");
+ doFindInContext(cm, #_staticFooInC, C._staticFooInC);
+ dontFindInContext(cm, #_staticInS);
+ dontFindInContext(cm, #_staticFooInS);
+ doFindInContext(cm, #_globalFoo, _globalFoo);
+ doFindInContext(cm, #_globalVariable, "globalVariable");
+
+ dontFindInContext(cm, p('_local'));
+ dontFindInContext(cm, p('_innerLocal'));
+ dontFindInContext(cm, p('_method'));
+ dontFindInContext(cm, p('_instanceInC'));
+ dontFindInContext(cm, p('_staticInC'));
+ dontFindInContext(cm, p('_staticFooInC'));
+ dontFindInContext(cm, p('_staticInS'));
+ dontFindInContext(cm, p('_staticFooInS'));
+ dontFindInContext(cm, p('_globalFoo'));
+ dontFindInContext(cm, p('_globalVariable'));
+}
diff --git a/tests/lib/mirrors/closure_mirror_find_in_context_test.dart b/tests/lib/mirrors/find_in_context_test.dart
similarity index 94%
rename from tests/lib/mirrors/closure_mirror_find_in_context_test.dart
rename to tests/lib/mirrors/find_in_context_test.dart
index b26a140..348cd3a 100644
--- a/tests/lib/mirrors/closure_mirror_find_in_context_test.dart
+++ b/tests/lib/mirrors/find_in_context_test.dart
@@ -2,6 +2,8 @@
// 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=--support_find_in_context=true
+
import "dart:mirrors";
import "stringify.dart";
@@ -69,12 +71,16 @@
Expect.equals(null, result);
result = cm.findInContext(#staticFooInS);
+ Expect.isFalse(result is InstanceMirror);
+ Expect.equals(null, result);
+
+ result = cm.findInContext(#S.staticFooInS);
Expect.isTrue(result is ClosureMirror);
expect("Instance(value = staticFooInS)", result.apply(const []));
result = cm.findInContext(#C.staticFooInS);
- Expect.isTrue(result is ClosureMirror);
- expect("Instance(value = staticFooInS)", result.apply(const []));
+ Expect.isFalse(result is InstanceMirror);
+ Expect.equals(null, result);
result = cm.findInContext(#C.staticInC);
expect("Instance(value = staticInC)", result);
diff --git a/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart b/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart
index c6f2b16..92426d5 100644
--- a/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart
+++ b/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart
@@ -11,11 +11,20 @@
import 'generics_helper.dart';
class Super<T, R extends T> {}
-
class Fixed extends Super<num, int> {}
-class Generic<X, Y> extends Super<X, Y> {} /// 02: static type warning
+class Generic<X, Y> extends Super<X, Y> {} /// 02: static type warning
class Malbounded extends Super<num, String> {} /// 01: static type warning
+bool inCheckedMode() {
+ try {
+ var s = 'string';
+ int i = s;
+ } catch(e) {
+ return true;
+ }
+ return false;
+}
+
main() {
ClassMirror superDecl = reflectClass(Super);
ClassMirror superOfNumAndInt = reflectClass(Fixed).superclass;
@@ -23,18 +32,28 @@
ClassMirror superOfXAndY = genericDecl.superclass; /// 02: continued
ClassMirror genericOfNumAndDouble = reflect(new Generic<num, double>()).type; /// 02: continued
ClassMirror superOfNumAndDouble = genericOfNumAndDouble.superclass; /// 02: continued
- ClassMirror genericOfNumAndBool = reflect(new Generic<num, bool>()).type; /// 02: static type warning, dynamic type error
- ClassMirror superOfNumAndBool = genericOfNumAndBool.superclass; /// 02: continued
ClassMirror superOfNumAndString = reflectClass(Malbounded).superclass; /// 01: continued
+ try {
+ ClassMirror genericOfNumAndBool = reflect(new Generic<num, bool>()).type; /// 02: static type warning
+ ClassMirror superOfNumAndBool = genericOfNumAndBool.superclass; /// 02: continued
+ Expect.isFalse(genericOfNumAndBool.isOriginalDeclaration); /// 02: continued
+ Expect.isFalse(superOfNumAndBool.isOriginalDeclaration); /// 02: continued
+ typeParameters(genericOfNumAndBool, [#X, #Y]); /// 02: continued
+ typeParameters(superOfNumAndBool, [#T, #R]); /// 02: continued
+ typeArguments(genericOfNumAndBool, [reflectClass(num), reflectClass(bool)]); /// 02: continued
+ typeArguments(superOfNumAndBool, [reflectClass(num), reflectClass(bool)]); /// 02: continued
+ Expect.isFalse(inCheckedMode()); /// 02: continued
+ } on TypeError catch(e) {
+ Expect.isTrue(inCheckedMode());
+ }
+
Expect.isTrue(superDecl.isOriginalDeclaration);
Expect.isFalse(superOfNumAndInt.isOriginalDeclaration);
Expect.isTrue(genericDecl.isOriginalDeclaration); /// 02: continued
Expect.isFalse(superOfXAndY.isOriginalDeclaration); /// 02: continued
Expect.isFalse(genericOfNumAndDouble.isOriginalDeclaration); /// 02: continued
Expect.isFalse(superOfNumAndDouble.isOriginalDeclaration); /// 02: continued
- Expect.isFalse(genericOfNumAndBool.isOriginalDeclaration); /// 02: continued
- Expect.isFalse(superOfNumAndBool.isOriginalDeclaration); /// 02: continued
Expect.isFalse(superOfNumAndString.isOriginalDeclaration); /// 01: continued
TypeVariableMirror tFromSuper = superDecl.typeVariables[0];
@@ -53,8 +72,6 @@
typeParameters(superOfXAndY, [#T, #R]); /// 02: continued
typeParameters(genericOfNumAndDouble, [#X, #Y]); /// 02: continued
typeParameters(superOfNumAndDouble, [#T, #R]); /// 02: continued
- typeParameters(genericOfNumAndBool, [#X, #Y]); /// 02: continued
- typeParameters(superOfNumAndBool, [#T, #R]); /// 02: continued
typeParameters(superOfNumAndString, [#T, #R]); /// 01: continued
typeArguments(superDecl, []);
@@ -63,7 +80,5 @@
typeArguments(superOfXAndY, [xFromGeneric, yFromGeneric]); /// 02: continued
typeArguments(genericOfNumAndDouble, [reflectClass(num), reflectClass(double)]); /// 02: continued
typeArguments(superOfNumAndDouble, [reflectClass(num), reflectClass(double)]); /// 02: continued
- typeArguments(genericOfNumAndBool, [reflectClass(num), reflectClass(bool)]); /// 02: continued
- typeArguments(superOfNumAndBool, [reflectClass(num), reflectClass(bool)]); /// 02: continued
typeArguments(superOfNumAndString, [reflectClass(num), reflectClass(String)]); /// 01: continued
}
diff --git a/tests/lib/mirrors/generic_bounded_test.dart b/tests/lib/mirrors/generic_bounded_test.dart
index dec144a..3cfac14 100644
--- a/tests/lib/mirrors/generic_bounded_test.dart
+++ b/tests/lib/mirrors/generic_bounded_test.dart
@@ -16,6 +16,16 @@
class Generic<R> extends Super<R> {} /// 02: static type warning
class Malbounded extends Super<String> {} /// 01: static type warning
+bool inCheckedMode() {
+ try {
+ var s = 'string';
+ int i = s;
+ } catch(e) {
+ return true;
+ }
+ return false;
+}
+
main() {
ClassMirror superDecl = reflectClass(Super);
ClassMirror superOfInt = reflectClass(Fixed).superclass;
@@ -23,8 +33,21 @@
ClassMirror superOfR = genericDecl.superclass; /// 02: continued
ClassMirror genericOfDouble = reflect(new Generic<double>()).type; /// 02: continued
ClassMirror superOfDouble = genericOfDouble.superclass; /// 02: continued
- ClassMirror genericOfBool = reflect(new Generic<bool>()).type; /// 02: static type warning, dynamic type error
- ClassMirror superOfBool = genericOfBool.superclass; /// 02: continued
+
+ try {
+ ClassMirror genericOfBool = reflect(new Generic<bool>()).type; /// 02: static type warning
+ ClassMirror superOfBool = genericOfBool.superclass; /// 02: continued
+ Expect.isFalse(genericOfBool.isOriginalDeclaration); /// 02: continued
+ Expect.isFalse(superOfBool.isOriginalDeclaration); /// 02: continued
+ typeParameters(genericOfBool, [#R]); /// 02: continued
+ typeParameters(superOfBool, [#T]); /// 02: continued
+ typeArguments(genericOfBool, [reflectClass(bool)]); /// 02: continued
+ typeArguments(superOfBool, [reflectClass(bool)]); /// 02: continued
+ Expect.isFalse(inCheckedMode()); /// 02: continued
+ } on TypeError catch(e) {
+ Expect.isTrue(inCheckedMode());
+ }
+
ClassMirror superOfString = reflectClass(Malbounded).superclass; /// 01: continued
Expect.isTrue(superDecl.isOriginalDeclaration);
@@ -33,8 +56,7 @@
Expect.isFalse(superOfR.isOriginalDeclaration); /// 02: continued
Expect.isFalse(genericOfDouble.isOriginalDeclaration); /// 02: continued
Expect.isFalse(superOfDouble.isOriginalDeclaration); /// 02: continued
- Expect.isFalse(genericOfBool.isOriginalDeclaration); /// 02: continued
- Expect.isFalse(superOfBool.isOriginalDeclaration); /// 02: continued
+
Expect.isFalse(superOfString.isOriginalDeclaration); /// 01: continued
TypeVariableMirror tFromSuper = superDecl.typeVariables.single;
@@ -49,8 +71,6 @@
typeParameters(superOfR, [#T]); /// 02: continued
typeParameters(genericOfDouble, [#R]); /// 02: continued
typeParameters(superOfDouble, [#T]); /// 02: continued
- typeParameters(genericOfBool, [#R]); /// 02: continued
- typeParameters(superOfBool, [#T]); /// 02: continued
typeParameters(superOfString, [#T]); /// 01: continued
typeArguments(superDecl, []);
@@ -59,7 +79,5 @@
typeArguments(superOfR, [rFromGeneric]); /// 02: continued
typeArguments(genericOfDouble, [reflectClass(double)]); /// 02: continued
typeArguments(superOfDouble, [reflectClass(double)]); /// 02: continued
- typeArguments(genericOfBool, [reflectClass(bool)]); /// 02: continued
- typeArguments(superOfBool, [reflectClass(bool)]); /// 02: continued
typeArguments(superOfString, [reflectClass(String)]); /// 01: continued
}
diff --git a/tests/lib/mirrors/generic_f_bounded_test.dart b/tests/lib/mirrors/generic_f_bounded_test.dart
index 00e4fbb..bd36860 100644
--- a/tests/lib/mirrors/generic_f_bounded_test.dart
+++ b/tests/lib/mirrors/generic_f_bounded_test.dart
@@ -27,8 +27,8 @@
Expect.isTrue(realDecl.isOriginalDeclaration);
Expect.isTrue(sorterDecl.isOriginalDeclaration);
Expect.isTrue(realSorterDecl.isOriginalDeclaration);
- Expect.isFalse(magnitudeOfReal.isOriginalDeclaration); /// 01: ok
- Expect.isFalse(sorterOfReal.isOriginalDeclaration); /// 01: ok
+ Expect.isFalse(magnitudeOfReal.isOriginalDeclaration);
+ Expect.isFalse(sorterOfReal.isOriginalDeclaration);
TypeVariableMirror tFromMagnitude = magnitudeDecl.typeVariables.single;
TypeVariableMirror rFromSorter = sorterDecl.typeVariables.single;
@@ -52,7 +52,7 @@
typeArguments(realDecl, []);
typeArguments(sorterDecl, []);
typeArguments(realSorterDecl, []);
- typeArguments(magnitudeOfReal, [realDecl]); /// 01: ok
+ typeArguments(magnitudeOfReal, [realDecl]); /// 01: ok
typeArguments(sorterOfReal, [realDecl]); /// 01: ok
typeArguments(magnitudeOfR, [rFromSorter]);
}
diff --git a/tests/lib/mirrors/generic_superclass_test.dart b/tests/lib/mirrors/generic_superclass_test.dart
new file mode 100644
index 0000000..ebf4c8c
--- /dev/null
+++ b/tests/lib/mirrors/generic_superclass_test.dart
@@ -0,0 +1,120 @@
+// 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 'package:expect/expect.dart';
+import 'dart:mirrors';
+
+
+class A<T> {}
+class B extends A<U>{}
+class C extends A<C> {}
+class D<T> extends A<T> {}
+class E<X,Y> extends G<H<Y>> {}
+class F<X> implements A<X> {}
+class FF<X,Y> implements G<H<Y>> {}
+class G<T> {}
+class H<T> {}
+class U {}
+class R {}
+
+void testOriginals() {
+ ClassMirror a = reflectClass(A);
+ ClassMirror b = reflectClass(B);
+ ClassMirror c = reflectClass(C);
+ ClassMirror d = reflectClass(D);
+ ClassMirror e = reflectClass(E);
+ ClassMirror f = reflectClass(F);
+ ClassMirror ff = reflectClass(FF);
+ ClassMirror superA = a.superclass;
+ ClassMirror superB = b.superclass;
+ ClassMirror superC = c.superclass;
+ ClassMirror superD = d.superclass;
+ ClassMirror superE = e.superclass;
+ ClassMirror superInterfaceF = f.superinterfaces[0];
+ ClassMirror superInterfaceFF = ff.superinterfaces[0];
+
+ TypeVariableMirror aT = a.typeVariables[0];
+ TypeVariableMirror dT = d.typeVariables[0];
+ TypeVariableMirror eX = e.typeVariables[0];
+ TypeVariableMirror eY = e.typeVariables[1];
+ TypeVariableMirror fX = f.typeVariables[0];
+ TypeVariableMirror feX = ff.typeVariables[0];
+ TypeVariableMirror feY = ff.typeVariables[1];
+
+ Expect.isTrue(superA.isOriginalDeclaration);
+ Expect.isFalse(superB.isOriginalDeclaration);
+ Expect.isFalse(superC.isOriginalDeclaration);
+ Expect.isFalse(superD.isOriginalDeclaration);
+ Expect.isFalse(superE.isOriginalDeclaration);
+ Expect.isFalse(superInterfaceF.isOriginalDeclaration);
+ Expect.isFalse(superInterfaceFF.isOriginalDeclaration);
+
+ Expect.equals(reflectClass(Object), superA);
+ Expect.equals(reflect(new A<U>()).type, superB);
+ Expect.equals(reflect(new A<C>()).type, superC); /// 01: ok
+ Expect.equals(reflect(new U()).type, superB.typeArguments[0]);
+ Expect.equals(reflect(new C()).type, superC.typeArguments[0]); /// 01: ok
+ Expect.equals(dT, superD.typeArguments[0]);
+ Expect.equals(eY, superE.typeArguments[0].typeArguments[0]);
+ Expect.equals(feY, superInterfaceFF.typeArguments[0].typeArguments[0]);
+ Expect.equals(fX, superInterfaceF.typeArguments[0]);
+}
+
+void testInstances() {
+ ClassMirror a = reflect(new A<U>()).type;
+ ClassMirror b = reflect(new B()).type;
+ ClassMirror c = reflect(new C()).type;
+ ClassMirror d = reflect(new D<U>()).type;
+ ClassMirror e = reflect(new E<U,R>()).type;
+ ClassMirror e0 = reflect(new E<U,H<R>>()).type;
+ ClassMirror ff = reflect(new FF<U,R>()).type;
+ ClassMirror f = reflect(new F<U>()).type;
+ ClassMirror u = reflect(new U()).type;
+ ClassMirror r = reflect(new R()).type;
+ ClassMirror hr = reflect(new H<R>()).type;
+
+ ClassMirror superA = a.superclass;
+ ClassMirror superB = b.superclass;
+ ClassMirror superC = c.superclass;
+ ClassMirror superD = d.superclass;
+ ClassMirror superE = e.superclass;
+ ClassMirror superE0 = e0.superclass;
+ ClassMirror superInterfaceF = f.superinterfaces[0];
+ ClassMirror superInterfaceFF = ff.superinterfaces[0];
+
+ Expect.isTrue(superA.isOriginalDeclaration);
+ Expect.isFalse(superB.isOriginalDeclaration);
+ Expect.isFalse(superC.isOriginalDeclaration);
+ Expect.isFalse(superD.isOriginalDeclaration);
+ Expect.isFalse(superE.isOriginalDeclaration);
+ Expect.isFalse(superE0.isOriginalDeclaration);
+ Expect.isFalse(superInterfaceF.isOriginalDeclaration);
+ Expect.isFalse(superInterfaceFF.isOriginalDeclaration);
+
+ Expect.equals(reflectClass(Object), superA);
+ Expect.equals(reflect(new A<U>()).type, superB);
+ Expect.equals(reflect(new A<C>()).type, superC); /// 01: ok
+ Expect.equals(reflect(new A<U>()).type, superD);
+ Expect.equals(reflect(new G<H<R>>()).type, superE);
+ Expect.equals(reflect(new G<H<H<R>>>()).type, superE0);
+ Expect.equals(reflect(new G<H<R>>()).type, superInterfaceFF);
+ Expect.equals(u, superB.typeArguments[0]);
+ Expect.equals(reflect(new C()).type, superC.typeArguments[0]); /// 01: ok
+ Expect.equals(u, superD.typeArguments[0]);
+ Expect.equals(r, superE.typeArguments[0].typeArguments[0]);
+ Expect.equals(hr, superE0.typeArguments[0].typeArguments[0]);
+ Expect.equals(r, superInterfaceFF.typeArguments[0].typeArguments[0]);
+ Expect.equals(u, superInterfaceF.typeArguments[0]);
+}
+
+void testObject() {
+ ClassMirror object = reflectClass(Object);
+ Expect.equals(null, object.superclass);
+}
+
+main() {
+ testOriginals();
+ testInstances();
+ testObject();
+}
\ No newline at end of file
diff --git a/tests/lib/mirrors/generic_type_mirror_test.dart b/tests/lib/mirrors/generic_type_mirror_test.dart
index 6b25a39..6b38328 100644
--- a/tests/lib/mirrors/generic_type_mirror_test.dart
+++ b/tests/lib/mirrors/generic_type_mirror_test.dart
@@ -11,27 +11,25 @@
set bar(V v) {}
W m() {}
V n() {}
+ H<V> p() {}
o(W w) {}
}
-
+class H<T> {}
class Bar {}
class Baz {}
-main() {
- testInstance();
- testOriginalDeclaration();
-}
-
void testInstance() {
ClassMirror foo = reflect((new Foo<Bar, Baz>())).type;
ClassMirror bar = reflect(new Bar()).type;
ClassMirror baz = reflect(new Baz()).type;
+ ClassMirror hOfBaz = reflect(new H<Baz>()).type;
VariableMirror field = foo.variables.values.single;
MethodMirror getter = foo.getters.values.single;
MethodMirror setter = foo.setters.values.single;
MethodMirror m = foo.methods[const Symbol('m')];
MethodMirror n = foo.methods[const Symbol('n')];
MethodMirror o = foo.methods[const Symbol('o')];
+ MethodMirror p = foo.methods[const Symbol('p')];
Expect.equals(foo, field.owner);
Expect.equals(foo, getter.owner);
@@ -39,12 +37,17 @@
Expect.equals(foo, m.owner);
Expect.equals(foo, n.owner);
Expect.equals(foo, o.owner);
+ Expect.equals(foo, p.owner);
Expect.equals(baz, field.type); /// 01: ok
Expect.equals(baz, getter.returnType);
Expect.equals(bar, m.returnType);
Expect.equals(baz, n.returnType);
Expect.equals(bar, o.parameters.single.type);
+ Expect.equals(hOfBaz, p.returnType); /// 02: ok
+ Expect.equals(1, p.returnType.typeArguments.length);
+ Expect.equals(baz, p.returnType.typeArguments[0]); /// 02: ok
+
Expect.equals(baz, setter.parameters.single.type);
}
@@ -58,6 +61,7 @@
MethodMirror m = foo.methods[const Symbol('m')];
MethodMirror n = foo.methods[const Symbol('n')];
MethodMirror o = foo.methods[const Symbol('o')];
+ MethodMirror p = foo.methods[const Symbol('p')];
TypeVariableMirror w = foo.typeVariables[0];
TypeVariableMirror v = foo.typeVariables[1];
@@ -67,12 +71,20 @@
Expect.equals(foo, m.owner);
Expect.equals(foo, n.owner);
Expect.equals(foo, o.owner);
+ Expect.equals(foo, p.owner);
Expect.equals(v, field.type); /// 01: ok
Expect.equals(v, getter.returnType);
Expect.equals(w, m.returnType);
Expect.equals(v, n.returnType);
Expect.equals(w, o.parameters.single.type);
- Expect.equals(v, setter.parameters.single.type);
+ Expect.equals(1, p.returnType.typeArguments.length);
+ Expect.equals(v, p.returnType.typeArguments[0]);
+ Expect.equals(v, setter.parameters.single.type);
+}
+
+main() {
+ testInstance();
+ testOriginalDeclaration();
}
\ No newline at end of file
diff --git a/tests/lib/mirrors/generics_substitution_test.dart b/tests/lib/mirrors/generics_substitution_test.dart
index 8b2f16f..1d0e924 100644
--- a/tests/lib/mirrors/generics_substitution_test.dart
+++ b/tests/lib/mirrors/generics_substitution_test.dart
@@ -32,21 +32,21 @@
Symbol r(ClassMirror cm) => cm.variables[#r].type.simpleName;
Symbol s(ClassMirror cm) => cm.methods[#s].parameters[0].type.simpleName;
Symbol t(ClassMirror cm) => cm.methods[#t].returnType.simpleName;
-
- Expect.equals(#T, r(genericDecl.superclass));
+
+ Expect.equals(#T, r(genericDecl.superclass)); /// 01: ok
Expect.equals(#int, s(genericDecl.superclass));
Expect.equals(#T, t(genericDecl));
- Expect.equals(#String, r(genericOfString.superclass));
+ Expect.equals(#String, r(genericOfString.superclass)); /// 01: ok
Expect.equals(#int, s(genericOfString.superclass));
Expect.equals(#String, t(genericOfString));
- Expect.equals(#R, r(superGenericDecl));
+ Expect.equals(#R, r(superGenericDecl)); /// 01: ok
Expect.equals(#S, s(superGenericDecl));
- Expect.equals(#T, r(superOfTAndInt));
+ Expect.equals(#T, r(superOfTAndInt)); /// 01: ok
Expect.equals(#int, s(superOfTAndInt));
- Expect.equals(#String, r(superOfStringAndInt));
+ Expect.equals(#String, r(superOfStringAndInt)); /// 01: ok
Expect.equals(#int, s(superOfStringAndInt));
}
diff --git a/tests/lib/mirrors/invoke_closurization_test.dart b/tests/lib/mirrors/invoke_closurization_test.dart
index 28cdd56..1039161 100644
--- a/tests/lib/mirrors/invoke_closurization_test.dart
+++ b/tests/lib/mirrors/invoke_closurization_test.dart
@@ -35,33 +35,6 @@
Expect.equals("A:B:C", result.reflectee('A', 'B', 'C'));
}
-testAsync() {
- var future;
-
- C c = new C();
- InstanceMirror im = reflect(c);
- future = im.getFieldAsync(#instanceMethod);
- expectValueThen(future, (result) {
- Expect.isTrue(result.reflectee is Function, "Should be closure");
- Expect.equals("A+B+C", result.reflectee('A', 'B', 'C'));
- });
-
- ClassMirror cm = reflectClass(C);
- future = cm.getFieldAsync(#staticFunction);
- expectValueThen(future, (result) {
- Expect.isTrue(result.reflectee is Function, "Should be closure");
- Expect.equals("A-B-C", result.reflectee('A', 'B', 'C'));
- });
-
- LibraryMirror lm = cm.owner;
- future = lm.getFieldAsync(#libraryFunction);
- expectValueThen(future, (result) {
- Expect.isTrue(result.reflectee is Function, "Should be closure");
- Expect.equals("A:B:C", result.reflectee('A', 'B', 'C'));
- });
-}
-
main() {
testSync();
- testAsync();
}
diff --git a/tests/lib/mirrors/invoke_named_test.dart b/tests/lib/mirrors/invoke_named_test.dart
index da0b54b..feee0ab 100644
--- a/tests/lib/mirrors/invoke_named_test.dart
+++ b/tests/lib/mirrors/invoke_named_test.dart
@@ -121,99 +121,6 @@
'Unmatched named argument');
}
-testAsyncInvoke(ObjectMirror om) {
- Future<InstanceMirror> future;
-
- future = om.invokeAsync(const Symbol('a'), ['X']);
- expectValueThen(future, (result) {
- Expect.equals('X-B-null', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('a'), ['X'], {const Symbol('b') : 'Y'});
- expectValueThen(future, (result) {
- Expect.equals('X-Y-null', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('a'), ['X'], {const Symbol('c') : 'Z', const Symbol('b') : 'Y'});
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('a'), []);
- expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
- future = om.invokeAsync(const Symbol('a'), ['X', 'Y']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = om.invokeAsync(const Symbol('a'), ['X'], {const Symbol('undef') : 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- future = om.invokeAsync(const Symbol('b'), []);
- expectValueThen(future, (result) {
- Expect.equals('A-null-null', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('b'), [], {const Symbol('a') : 'X'});
- expectValueThen(future, (result) {
- Expect.equals('X-null-null', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('b'), [], {const Symbol('b') :'Y', const Symbol('c') :'Z', const Symbol('a') :'X'});
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('b'), ['X']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = om.invokeAsync(const Symbol('b'), ['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
- future = om.invokeAsync(const Symbol('c'), ['X']);
- expectValueThen(future, (result) {
- Expect.equals('X-null-C', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('c'), ['X', 'Y']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-C', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('c'), ['X', 'Y', 'Z']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('c'), []);
- expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
- future = om.invokeAsync(const Symbol('c'), ['X', 'Y', 'Z', 'W']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = om.invokeAsync(const Symbol('c'), ['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- future = om.invokeAsync(const Symbol('d'), []);
- expectValueThen(future, (result) {
- Expect.equals('null-B-C', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('d'), ['X']);
- expectValueThen(future, (result) {
- Expect.equals('X-B-C', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('d'), ['X', 'Y']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-C', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('d'), ['X', 'Y', 'Z']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('d'), ['X', 'Y', 'Z', 'W']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = om.invokeAsync(const Symbol('d'), ['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
- future = om.invokeAsync(const Symbol('e'), ['X', 'Y', 'Z']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = om.invokeAsync(const Symbol('e'), ['X']);
- expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
- future = om.invokeAsync(const Symbol('e'), ['X', 'Y', 'Z', 'W']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = om.invokeAsync(const Symbol('e'), ['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-}
-
testSyncNewInstance() {
ClassMirror cm = reflectClass(E);
InstanceMirror result;
@@ -291,102 +198,6 @@
'Unmatched named argument');
}
-testAsyncNewInstance() {
- ClassMirror cm = reflectClass(E);
- Future<InstanceMirror> future;
-
- future = cm.newInstanceAsync(const Symbol(''), ['X']);
- expectValueThen(future, (result) {
- Expect.equals('X-B-null', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol(''), ['X'], {const Symbol('b') : 'Y'});
- expectValueThen(future, (result) {
- Expect.equals('X-Y-null', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol(''), ['X'], {const Symbol('c') : 'Z', const Symbol('b') : 'Y'});
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol(''), []);
- expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
- future = cm.newInstanceAsync(const Symbol(''), ['X', 'Y']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.newInstanceAsync(const Symbol(''), ['X'], {const Symbol('undef') : 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- future = cm.newInstanceAsync(const Symbol('b'), []);
- expectValueThen(future, (result) {
- Expect.equals('A-null-null', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('b'), [], {const Symbol('a') : 'X'});
- expectValueThen(future, (result) {
- Expect.equals('X-null-null', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('b'), [], {const Symbol('b') :'Y', const Symbol('c') :'Z', const Symbol('a') :'X'});
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('b'), ['X']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.newInstanceAsync(const Symbol('b'), ['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- future = cm.newInstanceAsync(const Symbol('c'), ['X']);
- expectValueThen(future, (result) {
- Expect.equals('X-null-C', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('c'), ['X', 'Y']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-C', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('c'), ['X', 'Y', 'Z']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('c'), []);
- expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
- future = cm.newInstanceAsync(const Symbol('c'), ['X', 'Y', 'Z', 'W']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.newInstanceAsync(const Symbol('c'), ['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- future = cm.newInstanceAsync(const Symbol('d'), []);
- expectValueThen(future, (result) {
- Expect.equals('null-B-C', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('d'), ['X']);
- expectValueThen(future, (result) {
- Expect.equals('X-B-C', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('d'), ['X', 'Y']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-C', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('d'), ['X', 'Y', 'Z']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('d'), ['X', 'Y', 'Z', 'W']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.newInstanceAsync(const Symbol('d'), ['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- future = cm.newInstanceAsync(const Symbol('e'), ['X', 'Y', 'Z']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('e'), ['X']);
- expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
- future = cm.newInstanceAsync(const Symbol('e'), ['X', 'Y', 'Z', 'W']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.newInstanceAsync(const Symbol('e'), ['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-}
-
testSyncApply() {
ClosureMirror cm;
InstanceMirror result;
@@ -469,125 +280,18 @@
'Unmatched named argument');
}
-testAsyncApply() {
- ClosureMirror cm;
- Future<InstanceMirror> future;
-
- cm = reflect(a);
- future = cm.applyAsync(['X']);
- expectValueThen(future, (result) {
- Expect.equals('X-B-null', result.reflectee);
- });
- future = cm.applyAsync(['X'], {const Symbol('b') : 'Y'});
- expectValueThen(future, (result) {
- Expect.equals('X-Y-null', result.reflectee);
- });
- future = cm.applyAsync(['X'], {const Symbol('c') : 'Z', const Symbol('b') : 'Y'});
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = cm.applyAsync([]);
- expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
- future = cm.applyAsync(['X', 'Y']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.applyAsync(['X'], {const Symbol('undef') : 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- cm = reflect(b);
- future = cm.applyAsync([]);
- expectValueThen(future, (result) {
- Expect.equals('A-null-null', result.reflectee);
- });
- future = cm.applyAsync([], {const Symbol('a') : 'X'});
- expectValueThen(future, (result) {
- Expect.equals('X-null-null', result.reflectee);
- });
- future = cm.applyAsync([], {const Symbol('b') :'Y', const Symbol('c') :'Z', const Symbol('a') :'X'});
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = cm.applyAsync(['X']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.applyAsync(['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- cm = reflect(c);
- future = cm.applyAsync(['X']);
- expectValueThen(future, (result) {
- Expect.equals('X-null-C', result.reflectee);
- });
- future = cm.applyAsync(['X', 'Y']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-C', result.reflectee);
- });
- future = cm.applyAsync(['X', 'Y', 'Z']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = cm.applyAsync([]);
- expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
- future = cm.applyAsync(['X', 'Y', 'Z', 'W']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.applyAsync(['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- cm = reflect(d);
- future = cm.applyAsync([]);
- expectValueThen(future, (result) {
- Expect.equals('null-B-C', result.reflectee);
- });
- future = cm.applyAsync(['X']);
- expectValueThen(future, (result) {
- Expect.equals('X-B-C', result.reflectee);
- });
- future = cm.applyAsync(['X', 'Y']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-C', result.reflectee);
- });
- future = cm.applyAsync(['X', 'Y', 'Z']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = cm.applyAsync(['X', 'Y', 'Z', 'W']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.applyAsync(['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
- cm = reflect(e);
- future = cm.applyAsync(['X', 'Y', 'Z']);
- expectValueThen(future, (result) {
- Expect.equals('X-Y-Z', result.reflectee);
- });
- future = cm.applyAsync(['X']);
- expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
- future = cm.applyAsync(['X', 'Y', 'Z', 'W']);
- expectError(future, isNoSuchMethodError, 'Extra positional arguments');
- future = cm.applyAsync(['X'], {const Symbol('undef'): 'Y'});
- expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-}
-
main() {
isDart2js = true; /// 01: ok
testSyncInvoke(reflect(new C())); // InstanceMirror
- if (!isDart2js) testSyncInvoke(reflectClass(D)); // ClassMirror
- LibraryMirror lib = reflectClass(D).owner;
- if (!isDart2js) testSyncInvoke(lib); // LibraryMirror
-
- testAsyncInvoke(reflect(new C())); // InstanceMirror
if (isDart2js) return;
- testAsyncInvoke(reflectClass(D)); // ClassMirror
- testAsyncInvoke(lib); // LibraryMirror
+ testSyncInvoke(reflectClass(D)); // ClassMirror
+ LibraryMirror lib = reflectClass(D).owner;
+ testSyncInvoke(lib); // LibraryMirror
testSyncNewInstance();
- testAsyncNewInstance();
testSyncApply();
- testAsyncApply();
}
diff --git a/tests/lib/mirrors/invoke_private_test.dart b/tests/lib/mirrors/invoke_private_test.dart
index 160d3ea..091ba31 100644
--- a/tests/lib/mirrors/invoke_private_test.dart
+++ b/tests/lib/mirrors/invoke_private_test.dart
@@ -2,12 +2,11 @@
// 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 test.invoke_test;
+library test.invoke_private_test;
import 'dart:mirrors';
import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
class C {
var _field;
diff --git a/tests/lib/mirrors/invoke_test.dart b/tests/lib/mirrors/invoke_test.dart
index 2d225d1..ec5056f 100644
--- a/tests/lib/mirrors/invoke_test.dart
+++ b/tests/lib/mirrors/invoke_test.dart
@@ -9,7 +9,6 @@
import 'dart:async' show Future;
import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
class C {
var field;
@@ -34,33 +33,6 @@
set librarySetter(v) => libraryField = 'lset $v';
libraryFunction(x,y) => '$x$y';
-Future expectValueThen(Future future, Function onValue) {
- asyncStart();
- wrappedOnValue(resultIn) {
- var resultOut = onValue(resultIn);
- asyncEnd();
- return resultOut;
- }
- onError(e) {
- Expect.fail("Value expected. ($e)");
- }
- return future.then(wrappedOnValue, onError: onError);
-}
-
-Future expectError(Future future, Function errorPredicate, String reason) {
- asyncStart();
- onValue(result) {
- Expect.fail("Error expected ($reason)");
- }
- onError(e) {
- asyncEnd();
- if (!errorPredicate(e)) {
- Expect.fail("Unexpected error ($reason)");
- }
- }
- return future.then(onValue, onError: onError);
-}
-
bool isNoSuchMethodError(e) {
return e is NoSuchMethodError;
}
@@ -181,177 +153,6 @@
'Not defined');
}
-testAsync() {
- var future;
-
- // InstanceMirror invoke
- C c = new C();
- InstanceMirror im = reflect(c);
- future = im.invokeAsync(const Symbol('method'), [2,4,8]);
- expectValueThen(future, (result) {
- Expect.equals('2+4+8', result.reflectee);
- });
- future = im.invokeAsync(const Symbol('method'), [im,im,im]);
- expectValueThen(future, (result) {
- Expect.equals('a C+a C+a C', result.reflectee);
- });
- future = im.invokeAsync(const Symbol('doesntExist'), [2,4,8]);
- expectValueThen(future, (result) {
- Expect.equals('DNU', result.reflectee);
- });
- future = im.invokeAsync(const Symbol('method'), [2, 4]); // Wrong arity.
- expectValueThen(future, (result) {
- Expect.equals('DNU', result.reflectee);
- });
-
- // InstanceMirror invokeGetter
- future = im.getFieldAsync(const Symbol('getter'));
- expectValueThen(future, (result) {
- Expect.equals('get default', result.reflectee);
- });
- future = im.getFieldAsync(const Symbol('field'));
- expectValueThen(future, (result) {
- Expect.equals('default', result.reflectee);
- });
- future = im.getFieldAsync(const Symbol('doesntExist'));
- expectValueThen(future, (result) {
- Expect.equals('DNU', result.reflectee);
- });
-
- // InstanceMirror invokeSetter
- future = im.setFieldAsync(const Symbol('setter'), 'foo');
- expectValueThen(future, (result) {
- Expect.equals('foo', result.reflectee);
- Expect.equals('set foo', c.field);
- return im.setFieldAsync(const Symbol('field'), 'bar');
- }).then((result) {
- Expect.equals('bar', result.reflectee);
- Expect.equals('bar', c.field);
- return im.setFieldAsync(const Symbol('field'), im);
- }).then((result) {
- Expect.equals(im.reflectee, result.reflectee);
- Expect.equals(c, c.field);
- });
- future = im.setFieldAsync(const Symbol('doesntExist'), 'bar');
- expectValueThen(future, (result) {
- Expect.equals('bar', result.reflectee);
- });
-
-
- // ClassMirror invoke
- ClassMirror cm = reflectClass(C);
- future = cm.invokeAsync(const Symbol('staticFunction'),[3,4]);
- expectValueThen(future, (result) {
- Expect.equals('(3,4)', result.reflectee);
- });
- future = cm.invokeAsync(const Symbol('staticFunction'),[im,im]);
- expectValueThen(future, (result) {
- Expect.equals('(a C,a C)', result.reflectee);
- });
- future = cm.invokeAsync(const Symbol('doesntExist'),[im,im]);
- expectError(future, isNoSuchMethodError, 'Not defined');
- future = cm.invokeAsync(const Symbol('staticFunction'),[3]);
- expectError(future, isNoSuchMethodError, 'Wrong arity');
-
- // ClassMirror invokeGetter
- C.staticField = 'initial'; // Reset from synchronous test.
- future = cm.getFieldAsync(const Symbol('staticGetter'));
- expectValueThen(future, (result) {
- Expect.equals('sget initial', result.reflectee);
- });
- future = cm.getFieldAsync(const Symbol('staticField'));
- expectValueThen(future, (result) {
- Expect.equals('initial', result.reflectee);
- });
- future = cm.getFieldAsync(const Symbol('doesntExist'));
- expectError(future, isNoSuchMethodError, 'Not defined');
-
- // ClassMirror invokeSetter
- future = cm.setFieldAsync(const Symbol('staticSetter'), 'sfoo');
- expectValueThen(future, (result) {
- Expect.equals('sfoo', result.reflectee);
- Expect.equals('sset sfoo', C.staticField);
- return cm.setFieldAsync(const Symbol('staticField'), 'sbar');
- }).then((result) {
- Expect.equals('sbar', result.reflectee);
- Expect.equals('sbar', C.staticField);
- return cm.setFieldAsync(const Symbol('staticField'), im);
- }).then((result) {
- Expect.equals(im.reflectee, result.reflectee);
- Expect.equals(c, C.staticField);
- });
- future = cm.setFieldAsync(const Symbol('doesntExist'), 'sbar');
- expectError(future, isNoSuchMethodError, 'Not defined');
-
- // ClassMirror invokeConstructor
- future = cm.newInstanceAsync(const Symbol(''), []);
- expectValueThen(future, (result) {
- Expect.isTrue(result.reflectee is C);
- Expect.equals('default', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('named'), ['my value']);
- expectValueThen(future, (result) {
- Expect.isTrue(result.reflectee is C);
- Expect.equals('my value', result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('named'), [im]);
- expectValueThen(future, (result) {
- Expect.isTrue(result.reflectee is C);
- Expect.equals(c, result.reflectee.field);
- });
- future = cm.newInstanceAsync(const Symbol('doesntExist'), ['my value']);
- expectError(future, isNoSuchMethodError, 'Not defined');
- future = cm.newInstanceAsync(const Symbol('named'), []);
- expectError(future, isNoSuchMethodError, 'Wrong arity');
-
-
- // LibraryMirror invoke
- LibraryMirror lm = cm.owner;
- future = lm.invokeAsync(const Symbol('libraryFunction'),[':',')']);
- expectValueThen(future, (result) {
- Expect.equals(':)', result.reflectee);
- });
- future = lm.invokeAsync(const Symbol('libraryFunction'),[im,im]);
- expectValueThen(future, (result) {
- Expect.equals('a Ca C', result.reflectee);
- });
- future = lm.invokeAsync(const Symbol('doesntExist'),[im,im]);
- expectError(future, isNoSuchMethodError, 'Not defined');
- future = lm.invokeAsync(const Symbol('libraryFunction'),[':']);
- expectError(future, isNoSuchMethodError, 'Wrong arity');
-
- // LibraryMirror invokeGetter
- libraryField = 'a priori'; // Reset from synchronous test.
- future = lm.getFieldAsync(const Symbol('libraryGetter'));
- expectValueThen(future, (result) {
- Expect.equals('lget a priori', result.reflectee);
- });
- future = lm.getFieldAsync(const Symbol('libraryField'));
- expectValueThen(future, (result) {
- Expect.equals('a priori', result.reflectee);
- });
- future = lm.getFieldAsync(const Symbol('doesntExist'));
- expectError(future, isNoSuchMethodError, 'Not defined');
-
- // LibraryMirror invokeSetter
- future = lm.setFieldAsync(const Symbol('librarySetter'), 'lfoo');
- expectValueThen(future, (result) {
- Expect.equals('lfoo', result.reflectee);
- Expect.equals('lset lfoo', libraryField);
- return lm.setFieldAsync(const Symbol('libraryField'), 'lbar');
- }).then((result) {
- Expect.equals('lbar', result.reflectee);
- Expect.equals('lbar', libraryField);
- return lm.setFieldAsync(const Symbol('libraryField'), im);
- }).then((result) {
- Expect.equals(im.reflectee, result.reflectee);
- Expect.equals(c, libraryField);
- });
- future = lm.setFieldAsync(const Symbol('doesntExist'), 'lbar');
- expectError(future, isNoSuchMethodError, 'Not defined');
-}
-
main() {
testSync();
- testAsync();
}
diff --git a/tests/lib/mirrors/metadata_allowed_values_import.dart b/tests/lib/mirrors/metadata_allowed_values_import.dart
new file mode 100644
index 0000000..67df4e2
--- /dev/null
+++ b/tests/lib/mirrors/metadata_allowed_values_import.dart
@@ -0,0 +1,9 @@
+// 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.
+
+class Imported {
+ const Imported();
+ const Imported.named();
+ static const CONSTANT = 0;
+}
diff --git a/tests/lib/mirrors/metadata_allowed_values_test.dart b/tests/lib/mirrors/metadata_allowed_values_test.dart
new file mode 100644
index 0000000..77e7374
--- /dev/null
+++ b/tests/lib/mirrors/metadata_allowed_values_test.dart
@@ -0,0 +1,187 @@
+// 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 test.metadata_with_type_literal;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'metadata_allowed_values_import.dart'; // Unprefixed.
+import 'metadata_allowed_values_import.dart' as prefix;
+
+@A /// 01: compile-time error
+class A {}
+
+@B.CONSTANT
+class B {
+ static const CONSTANT = 3;
+}
+
+@C(3)
+class C {
+ final field;
+ const C(this.field);
+}
+
+@D.named(4)
+class D {
+ final field;
+ const D.named(this.field);
+}
+
+@E.NOT_CONSTANT /// 02: compile-time error
+class E {
+ static var NOT_CONSTANT = 3;
+}
+
+@F(6) /// 03: compile-time error
+class F {
+ final field;
+ F(this.field);
+}
+
+@G.named(4) /// 04: compile-time error
+class G {
+ final field;
+ G.named(this.field);
+}
+
+@H<int>() /// 05: compile-time error
+class H<T> {
+ const H();
+}
+
+@I[0] /// 06: compile-time error
+class I {}
+
+@this.toString /// 07: compile-time error
+class J {}
+
+@super.toString /// 08: compile-time error
+class K {}
+
+@L.func() /// 09: compile-time error
+class L {
+ static func() => 6;
+}
+
+@Imported /// 10: compile-time error
+class M {}
+
+@Imported()
+class N {}
+
+@Imported.named()
+class O {}
+
+@Imported.CONSTANT
+class P {}
+
+@prefix.Imported /// 11: compile-time error
+class Q {}
+
+@prefix.Imported()
+class R {}
+
+@prefix.Imported.named()
+class S {}
+
+@prefix.Imported.CONSTANT
+class T {}
+
+@U..toString() /// 12: compile-time error
+class U {}
+
+@V.tearOff /// 13: compile-time error
+class V {
+ static tearOff() {}
+}
+
+topLevelTearOff() => 4;
+
+@topLevelTearOff /// 14: compile-time error
+class W {}
+
+@TypeParameter /// 15: compile-time error
+class X<TypeParameter> {}
+
+@TypeParameter.member /// 16: compile-time error
+class Y<TypeParameter> {}
+
+@1 /// 17: compile-time error
+class Z {}
+
+@3.14 /// 18: compile-time error
+class AA {}
+
+@'string' /// 19: compile-time error
+class BB {}
+
+@#symbol /// 20: compile-time error
+class CC {}
+
+@['element'] /// 21: compile-time error
+class DD {}
+
+@{'key': 'value'} /// 22: compile-time error
+class EE {}
+
+@true /// 23: compile-time error
+class FF {}
+
+@false /// 24: compile-time error
+class GG {}
+
+@null /// 25: compile-time error
+class HH {}
+
+const a = const [1, 2, 3];
+@a
+class II {}
+
+@a[0] /// 26: compile-time error
+class JJ {}
+
+checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
+ Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata);
+}
+
+main() {
+ reflectClass(A).metadata;
+ checkMetadata(reflectClass(B), [B.CONSTANT]);
+ checkMetadata(reflectClass(C), [const C(3)]);
+ checkMetadata(reflectClass(D), [const D.named(4)]);
+ reflectClass(E).metadata;
+ reflectClass(F).metadata;
+ reflectClass(G).metadata;
+ reflectClass(H).metadata;
+ reflectClass(I).metadata;
+ reflectClass(J).metadata;
+ reflectClass(K).metadata;
+ reflectClass(L).metadata;
+ reflectClass(M).metadata;
+ checkMetadata(reflectClass(N), [const Imported()]);
+ checkMetadata(reflectClass(O), [const Imported.named()]);
+ checkMetadata(reflectClass(P), [Imported.CONSTANT]);
+ reflectClass(Q).metadata;
+ checkMetadata(reflectClass(R), [const prefix.Imported()]);
+ checkMetadata(reflectClass(S), [const prefix.Imported.named()]);
+ checkMetadata(reflectClass(T), [prefix.Imported.CONSTANT]);
+ reflectClass(U).metadata;
+ reflectClass(V).metadata;
+ reflectClass(W).metadata;
+ reflectClass(X).metadata;
+ reflectClass(Y).metadata;
+ reflectClass(Z).metadata;
+ reflectClass(AA).metadata;
+ reflectClass(BB).metadata;
+ reflectClass(CC).metadata;
+ reflectClass(DD).metadata;
+ reflectClass(EE).metadata;
+ reflectClass(FF).metadata;
+ reflectClass(GG).metadata;
+ reflectClass(HH).metadata;
+ reflectClass(II).metadata;
+ reflectClass(JJ).metadata;
+}
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index 69210a3..2cfde98 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -63,18 +63,6 @@
throws); // Wrong arity.
}
-testInstanceFieldAccess(mirrors) {
- var instance = new Class();
- var instMirror = reflect(instance);
-
- instMirror.setFieldAsync(#field, 44);
- instMirror.getFieldAsync(#field).then(
- expectAsync1((resultMirror) {
- expect(resultMirror.reflectee, equals(44));
- expect(instance.field, equals(44));
- }));
-}
-
/// In dart2js, lists, numbers, and other objects are treated special
/// and their methods are invoked through a techique called interceptors.
testIntercepted(mirrors) {
@@ -115,27 +103,6 @@
expect(libMirror.getField(#topLevelField).reflectee,
equals([91]));
expect(topLevelField, equals([91]));
-
- libMirror.setFieldAsync(#topLevelField, 42);
- future = libMirror.getFieldAsync(#topLevelField);
- future.then(expectAsync1((resultMirror) {
- expect(resultMirror.reflectee, equals(42));
- expect(topLevelField, equals(42));
- }));
-
- classMirror.setFieldAsync(#staticField, 43);
- future = classMirror.getFieldAsync(#staticField);
- future.then(expectAsync1((resultMirror) {
- expect(resultMirror.reflectee, equals(43));
- expect(Class.staticField, equals(43));
- }));
-
- instMirror.setFieldAsync(#field, 44);
- future = instMirror.getFieldAsync(#field);
- future.then(expectAsync1((resultMirror) {
- expect(resultMirror.reflectee, equals(44));
- expect(instance.field, equals(44));
- }));
}
testClosureMirrors(mirrors) {
@@ -150,11 +117,6 @@
expect(funcMirror.parameters.length, equals(3));
expect(mirror.apply([7, 8, 9]).reflectee, equals(24));
-
- var future = mirror.applyAsync([2, 4, 8]);
- future.then(expectAsync1((resultMirror) {
- expect(resultMirror.reflectee, equals(14));
- }));
}
testInvokeConstructor(mirrors) {
@@ -189,21 +151,6 @@
[10]);
expect(instanceMirror.reflectee is Class, equals(true));
expect(instanceMirror.reflectee.field, equals(30));
-
-
- var future = classMirror.newInstanceAsync(const Symbol(''), []);
- future.then(expectAsync1((resultMirror) {
- var instance = resultMirror.reflectee;
- expect(instance is Class, equals(true));
- expect(instance.field, equals("default value"));
- }));
-
- future = classMirror.newInstanceAsync(#withInitialValue, [45]);
- future.then(expectAsync1((resultMirror) {
- var instance = resultMirror.reflectee;
- expect(instance is Class, equals(true));
- expect(instance.field, equals(45));
- }));
}
testReflectClass(mirrors) {
@@ -265,7 +212,6 @@
main() {
var mirrors = currentMirrorSystem();
test("Test reflective method invocation", () { testInvoke(mirrors); });
- test("Test instance field access", () { testInstanceFieldAccess(mirrors); });
test('Test intercepted objects', () { testIntercepted(mirrors); });
test("Test field access", () { testFieldAccess(mirrors); });
test("Test closure mirrors", () { testClosureMirrors(mirrors); });
diff --git a/tests/lib/mirrors/set_field_with_final_inheritance_test.dart b/tests/lib/mirrors/set_field_with_final_inheritance_test.dart
new file mode 100644
index 0000000..6e1cd39
--- /dev/null
+++ b/tests/lib/mirrors/set_field_with_final_inheritance_test.dart
@@ -0,0 +1,114 @@
+// 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 test.set_field_with_final_inheritance;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class S {
+ var sideEffect = 0;
+
+ var mutableWithInheritedMutable = 1;
+ final mutableWithInheritedFinal = 2;
+ set mutableWithInheritedSetter(x) => sideEffect = 3;
+
+ var finalWithInheritedMutable = 4;
+ final finalWithInheritedFinal = 5;
+ set finalWithInheritedSetter(x) => sideEffect = 6;
+
+ var setterWithInheritedMutable = 7;
+ final setterWithInheritedFinal = 8;
+ set setterWithInheritedSetter(x) => sideEffect = 9;
+}
+
+class C extends S {
+ var mutableWithInheritedMutable = 10;
+ var mutableWithInheritedFinal = 11;
+ var mutableWithInheritedSetter = 12;
+
+ final finalWithInheritedMutable = 13;
+ final finalWithInheritedFinal = 14;
+ final finalWithInheritedSetter = 15;
+
+ set setterWithInheritedMutable(x) => sideEffect = 16;
+ set setterWithInheritedFinal(x) => sideEffect = 17;
+ set setterWithInheritedSetter(x) => sideEffect = 18;
+
+ get superMutableWithInheritedMutable => super.mutableWithInheritedMutable;
+ get superMutableWithInheritedFinal => super.mutableWithInheritedFinal;
+
+ get superFinalWithInheritedMutable => super.finalWithInheritedMutable;
+ get superFinalWithInheritedFinal => super.finalWithInheritedFinal;
+
+ get superSetterWithInheritedMutable => super.setterWithInheritedMutable;
+ get superSetterWithInheritedFinal => super.setterWithInheritedFinal;
+}
+
+main() {
+ C c;
+ InstanceMirror im;
+
+ c = new C();
+ im = reflect(c);
+ Expect.equals(19, im.setField(#mutableWithInheritedMutable, 19).reflectee);
+ Expect.equals(19, c.mutableWithInheritedMutable);
+ Expect.equals(1, c.superMutableWithInheritedMutable);
+ Expect.equals(0, c.sideEffect);
+
+ c = new C();
+ im = reflect(c);
+ Expect.equals(20, im.setField(#mutableWithInheritedFinal, 20).reflectee);
+ Expect.equals(20, c.mutableWithInheritedFinal);
+ Expect.equals(2, c.superMutableWithInheritedFinal);
+ Expect.equals(0, c.sideEffect);
+
+ c = new C();
+ im = reflect(c);
+ Expect.equals(21, im.setField(#mutableWithInheritedSetter, 21).reflectee);
+ Expect.equals(21, c.mutableWithInheritedSetter);
+ Expect.equals(0, c.sideEffect);
+
+
+ c = new C();
+ im = reflect(c);
+ Expect.equals(22, im.setField(#finalWithInheritedMutable, 22).reflectee);
+ Expect.equals(13, c.finalWithInheritedMutable);
+ Expect.equals(22, c.superFinalWithInheritedMutable);
+ Expect.equals(0, c.sideEffect);
+
+ c = new C();
+ im = reflect(c);
+ Expect.throws(() => im.setField(#finalWithInheritedFinal, 23),
+ (e) => e is NoSuchMethodError);
+ Expect.equals(14, c.finalWithInheritedFinal);
+ Expect.equals(5, c.superFinalWithInheritedFinal);
+ Expect.equals(0, c.sideEffect);
+
+ c = new C();
+ im = reflect(c);
+ Expect.equals(24, im.setField(#finalWithInheritedSetter, 24).reflectee);
+ Expect.equals(15, c.finalWithInheritedSetter);
+ Expect.equals(6, c.sideEffect);
+
+
+ c = new C();
+ im = reflect(c);
+ Expect.equals(25, im.setField(#setterWithInheritedMutable, 25).reflectee);
+ Expect.equals(7, c.setterWithInheritedMutable);
+ Expect.equals(7, c.superSetterWithInheritedMutable);
+ Expect.equals(16, c.sideEffect);
+
+ c = new C();
+ im = reflect(c);
+ Expect.equals(26, im.setField(#setterWithInheritedFinal, 26).reflectee);
+ Expect.equals(8, c.setterWithInheritedFinal);
+ Expect.equals(8, c.superSetterWithInheritedFinal);
+ Expect.equals(17, c.sideEffect);
+
+ c = new C();
+ im = reflect(c);
+ Expect.equals(27, im.setField(#setterWithInheritedSetter, 27).reflectee);
+ Expect.equals(18, c.sideEffect);
+}
diff --git a/tests/lib/mirrors/set_field_with_final_test.dart b/tests/lib/mirrors/set_field_with_final_test.dart
new file mode 100644
index 0000000..63b07a5
--- /dev/null
+++ b/tests/lib/mirrors/set_field_with_final_test.dart
@@ -0,0 +1,38 @@
+// 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 test.set_field_with_final;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class C {
+ final instanceField = 1;
+ get instanceGetter => 2;
+ static final staticFinal = 3;
+ static get staticGetter => 4;
+}
+
+final toplevelFinal = 5;
+get toplevelGetter => 6;
+
+main() {
+ InstanceMirror im = reflect(new C());
+ Expect.throws(() => im.setField(#instanceField, 7),
+ (e) => e is NoSuchMethodError);
+ Expect.throws(() => im.setField(#instanceGetter, 8),
+ (e) => e is NoSuchMethodError);
+
+ ClassMirror cm = im.type;
+ Expect.throws(() => cm.setField(#staticFinal, 9),
+ (e) => e is NoSuchMethodError);
+ Expect.throws(() => cm.setField(#staticGetter, 10),
+ (e) => e is NoSuchMethodError);
+
+ LibraryMirror lm = cm.owner;
+ Expect.throws(() => lm.setField(#toplevelFinal, 11),
+ (e) => e is NoSuchMethodError);
+ Expect.throws(() => lm.setField(#toplevelGetter, 12),
+ (e) => e is NoSuchMethodError);
+}
diff --git a/tests/lib/typed_data/float32x4_transpose_test.dart b/tests/lib/typed_data/float32x4_transpose_test.dart
index f408d74..ecb39fb 100644
--- a/tests/lib/typed_data/float32x4_transpose_test.dart
+++ b/tests/lib/typed_data/float32x4_transpose_test.dart
@@ -15,14 +15,16 @@
var m1 = m[1];
var m2 = m[2];
var m3 = m[3];
- var t0 = m0.interleaveXY(m1);
- var t1 = m2.interleaveXY(m3);
- var t2 = m0.interleaveZW(m1);
- var t3 = m2.interleaveZW(m3);
- m[0] = t0.interleaveXYPairs(t1);
- m[1] = t0.interleaveZWPairs(t1);
- m[2] = t2.interleaveXYPairs(t3);
- m[3] = t2.interleaveZWPairs(t3);
+
+ var t0 = m0.shuffleMix(m1, Float32x4.XYXY);
+ var t1 = m2.shuffleMix(m3, Float32x4.XYXY);
+ m[0] = t0.shuffleMix(t1, Float32x4.XZXZ);
+ m[1] = t0.shuffleMix(t1, Float32x4.YWYW);
+
+ var t2 = m0.shuffleMix(m1, Float32x4.ZWZW);
+ var t3 = m2.shuffleMix(m3, Float32x4.ZWZW);
+ m[2] = t2.shuffleMix(t3, Float32x4.XZXZ);
+ m[3] = t2.shuffleMix(t3, Float32x4.YWYW);
}
void testTranspose(Float32x4List m, Float32x4List r) {
diff --git a/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart b/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart
index 5186b60..9b47e9c 100644
--- a/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart
+++ b/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart
@@ -12,7 +12,7 @@
testWithZWInXY() {
Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
- Float32x4 c = a.withZWInXY(b);
+ Float32x4 c = b.shuffleMix(a, Float32x4.ZWZW);
Expect.equals(7.0, c.x);
Expect.equals(8.0, c.y);
Expect.equals(3.0, c.z);
@@ -22,7 +22,7 @@
testInterleaveXY() {
Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
- Float32x4 c = a.interleaveXY(b);
+ Float32x4 c = a.shuffleMix(b, Float32x4.XYXY).shuffle(Float32x4.XZYW);
Expect.equals(1.0, c.x);
Expect.equals(5.0, c.y);
Expect.equals(2.0, c.z);
@@ -32,7 +32,7 @@
testInterleaveZW() {
Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
- Float32x4 c = a.interleaveZW(b);
+ Float32x4 c = a.shuffleMix(b, Float32x4.ZWZW).shuffle(Float32x4.XZYW);
Expect.equals(3.0, c.x);
Expect.equals(7.0, c.y);
Expect.equals(4.0, c.z);
@@ -42,7 +42,7 @@
testInterleaveXYPairs() {
Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
- Float32x4 c = a.interleaveXYPairs(b);
+ Float32x4 c = a.shuffleMix(b, Float32x4.XYXY);
Expect.equals(1.0, c.x);
Expect.equals(2.0, c.y);
Expect.equals(5.0, c.z);
@@ -52,7 +52,7 @@
testInterleaveZWPairs() {
Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
- Float32x4 c = a.interleaveZWPairs(b);
+ Float32x4 c = a.shuffleMix(b, Float32x4.ZWZW);
Expect.equals(3.0, c.x);
Expect.equals(4.0, c.y);
Expect.equals(7.0, c.z);
diff --git a/tests/lib/typed_data/uint32x4_shuffle_test.dart b/tests/lib/typed_data/uint32x4_shuffle_test.dart
new file mode 100644
index 0000000..f3335a8
--- /dev/null
+++ b/tests/lib/typed_data/uint32x4_shuffle_test.dart
@@ -0,0 +1,59 @@
+// 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=--optimization-counter-threshold=10
+
+// Library tag to be able to run in html test framework.
+library uint32x4_shuffle_test;
+
+import "package:expect/expect.dart";
+import 'dart:typed_data';
+
+void testShuffle() {
+ var m = new Uint32x4(1, 2, 3, 4);
+ var c;
+ c = m.shuffle(Uint32x4.WZYX);
+ Expect.equals(4, c.x);
+ Expect.equals(3, c.y);
+ Expect.equals(2, c.z);
+ Expect.equals(1, c.w);
+}
+
+void testShuffleNonConstant(mask) {
+ var m = new Uint32x4(1, 2, 3, 4);
+ var c;
+ c = m.shuffle(mask);
+ if (mask == 1) {
+ Expect.equals(2, c.x);
+ Expect.equals(1, c.y);
+ Expect.equals(1, c.z);
+ Expect.equals(1, c.w);
+ } else {
+ Expect.equals(Uint32x4.YYYY + 1, mask);
+ Expect.equals(3, c.x);
+ Expect.equals(2, c.y);
+ Expect.equals(2, c.z);
+ Expect.equals(2, c.w);
+ }
+}
+
+void testShuffleMix() {
+ var m = new Uint32x4(1, 2, 3, 4);
+ var n = new Uint32x4(5, 6, 7, 8);
+ var c = m.shuffleMix(n, Uint32x4.XYXY);
+ Expect.equals(1, c.x);
+ Expect.equals(2, c.y);
+ Expect.equals(5, c.z);
+ Expect.equals(6, c.w);
+}
+
+main() {
+ var xxxx = Uint32x4.XXXX + 1;
+ var yyyy = Uint32x4.YYYY + 1;
+ for (int i = 0; i < 20; i++) {
+ testShuffle();
+ testShuffleNonConstant(xxxx);
+ testShuffleNonConstant(yyyy);
+ testShuffleMix();
+ }
+}
\ No newline at end of file
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index d764b39..7bf4ccf 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -9,6 +9,8 @@
package/invalid_uri_test: Fail, OK # CompileTimeErrors intentionally
+issue14236_test: Pass, Fail, Crash # Issue 14516.
+
[ $runtime == vm ]
package/package_isolate_test: Fail # Issue 12474
diff --git a/tools/VERSION b/tools/VERSION
index 8b57d3e..b4cf83b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 8
-BUILD 9
+BUILD 10
PATCH 0
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 524b928..a19ba4d 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -4,36 +4,57 @@
part of $LIBRARYNAME;
-/**
- * A utility for retrieving data from a URL.
- *
- * HttpRequest can be used to obtain data from http, ftp, and file
- * protocols.
- *
- * For example, suppose we're developing these API docs, and we
- * wish to retrieve the HTML of the top-level page and print it out.
- * The easiest way to do that would be:
- *
- * HttpRequest.getString('http://api.dartlang.org').then((response) {
- * print(response);
- * });
- *
- * **Important**: With the default behavior of this class, your
- * code making the request should be served from the same origin (domain name,
- * port, and application layer protocol) as the URL you are trying to access
- * with HttpRequest. However, there are ways to
- * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#note-on-jsonp).
- *
- * See also:
- *
- * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
- * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
- * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
+ /**
+ * A client-side XHR request for getting data from a URL,
+ * formally known as XMLHttpRequest.
+ *
+ * HttpRequest can be used to obtain data from HTTP and FTP protocols,
+ * and is useful for AJAX-style page updates.
+ *
+ * The simplest way to get the contents of a text file, such as a
+ * JSON-formatted file, is with [getString].
+ * For example, the following code gets the contents of a JSON file
+ * and prints its length:
+ *
+ * var path = 'myData.json';
+ * HttpRequest.getString(path)
+ * .then((String fileContents) {
+ * print(fileContents.length);
+ * })
+ * .catchError((Error error) {
+ * print(error.toString());
+ * });
+ *
+ * ## Fetching data from other servers
+ *
+ * For security reasons, browsers impose restrictions on requests
+ * made by embedded apps.
+ * With the default behavior of this class,
+ * the code making the request must be served from the same origin
+ * (domain name, port, and application layer protocol)
+ * as the requested resource.
+ * In the example above, the myData.json file must be co-located with the
+ * app that uses it.
+ * You might be able to
+ * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
+ * by using CORS headers or JSONP.
+ *
+ * ## Other resources
+ *
+ * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
+ * a tutorial from _A Game of Darts_,
+ * shows two different ways to use HttpRequest to get a JSON file.
+ * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
+ * another tutorial from _A Game of Darts_,
+ * shows using HttpRequest with a custom server.
+ * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
+ * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
+ * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
*/
$(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
/**
- * Creates a URL get request for the specified [url].
+ * Creates a GET request for the specified [url].
*
* The server response must be a `text/` mime type for this request to
* succeed.
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 477a617..19d5bbb 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -1175,6 +1175,7 @@
}
args.add('--out=$outputFile');
args.add(inputFile);
+ args.addAll(optionsFromFile['sharedOptions']);
if (executable.endsWith('.dart')) {
// Run the compiler script via the Dart VM.
args.insert(0, executable);