dart2js: Add skeleton dart:_rti libary
- Skeleton Rti type
- Skeleton test
- Add dependency on command-line flag to get dart:_rti into platform dill
Change-Id: Idf383269c66c9951e23fd70a45ce65c54a973586
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104921
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index f0f64ff..9c0a6a5 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -377,6 +377,8 @@
return false;
case 'USE_CONTENT_SECURITY_POLICY':
return options.useContentSecurityPolicy;
+ case 'USE_NEW_RTI':
+ return options.experimentNewRti;
default:
return null;
}
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 7205568..beee35b 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -59,6 +59,8 @@
unmangleGlobalNameIfPreservedAnyways,
unmangleAllIdentifiersIfPreservedAnyways;
+import 'dart:_rti' as newRti show getRuntimeType;
+
part 'annotations.dart';
part 'constant_map.dart';
part 'instantiation.dart';
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
index e4b0f9d..6250aa0 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -391,6 +391,7 @@
}
Type getRuntimeType(var object) {
+ if (JS_GET_FLAG('USE_NEW_RTI')) return newRti.getRuntimeType(object);
return new TypeImpl(getRti(object));
}
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
new file mode 100644
index 0000000..489aef3
--- /dev/null
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This library contains support for runtime type information.
+library rti;
+
+import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show JSArray, JSUnmodifiableArray;
+
+/// An Rti object represents both a type (e.g `Map<int, String>`) and a type
+/// environment (`Map<int, String>` binds `Map.K=int` and `Map.V=String`).
+///
+/// There is a single [Rti] class to help reduce polymorphism in the JavaScript
+/// runtime. The class has a default constructor and no final fields so it can
+/// be created before much of the runtime exists.
+///
+/// The fields are declared in an order that gets shorter minified names for the
+/// more commonly used fields. (TODO: we should exploit the fact that an Rti
+/// instance never appears in a dynamic context, so does not need field names to
+/// be distinct from dynamic selectors).
+///
+class Rti {
+ /// JavaScript method for 'as' check. The method is called from generated code,
+ /// e.g. `o as T` generates something like `rtiForT._as(o)`.
+ dynamic _as;
+
+ /// JavaScript method for type check. The method is called from generated
+ /// code, e.g. parameter check for `T param` generates something like
+ /// `rtiForT._check(param)`.
+ dynamic _check;
+
+ /// JavaScript method for 'is' test. The method is called from generated
+ /// code, e.g. `o is T` generates something like `rtiForT._is(o)`.
+ dynamic _is;
+
+ /// Method called from generated code to evaluate a type environment recipe in
+ /// `this` type environment.
+ Rti _eval(String recipe) => _rtiEval(this, recipe);
+
+ /// Method called from generated code to extend `this` type environment with a
+ /// function type parameter.
+ Rti _bind1(Rti type) => _rtiBind1(this, type);
+
+ /// Method called from generated code to extend `this` type environment with a
+ /// tuple of function type parameters.
+ Rti _bind(Rti typeTuple) => _rtiBind(this, typeTuple);
+
+ // Precomputed derived types. These fields are used to hold derived types that
+ // are computed eagerly.
+ // TODO(sra): Implement precomputed type optimizations.
+ dynamic _precomputed1;
+ dynamic _precomputed2;
+ dynamic _precomputed3;
+ dynamic _precomputed4;
+
+ // The Type object corresponding to this Rti.
+ Type _typeCache;
+
+ /// The kind of Rti `this` is, one of the kindXXX constants below.
+ ///
+ /// We don't use an enum since we need to create Rti objects very early.
+ ///
+ /// The zero initializer ensures dart2js type analysis considers [_kind] is
+ /// non-nullable.
+ int _kind = 0;
+
+ // Terminal terms.
+ static const kindNever = 1;
+ static const kindDynamic = 2;
+ static const kindVoid = 3; // TODO(sra): Use `dynamic` instead?
+ static const kindAny = 4; // Dart1-style 'dynamic' for JS-interop.
+ // Unary terms.
+ static const kindStar = 5;
+ static const kindQuestion = 6;
+ static const kindFutureOr = 7;
+ // More complex terms.
+ static const kindInterface = 8;
+ // A vector of type parameters from enclosing functions and closures.
+ static const kindBinding = 9;
+ static const kindFunction = 10;
+ static const kindGenericFunction = 11;
+
+ /// Primary data associated with type.
+ ///
+ /// - Minified name of interface for interface types.
+ /// - Underlying type for unary terms.
+ /// - Class part of a type environment inside a generic class, or `null` for
+ /// type tuple.
+ /// - Return type of function types.
+ dynamic _primary;
+
+ String get interfaceName {
+ assert(_kind == kindInterface);
+ return JS('String', '#', _primary);
+ }
+
+ /// Additional data associated with type.
+ ///
+ /// - The type arguments of an interface type.
+ /// - The type arguments from enclosing functions and closures for a
+ /// kindBinding.
+ /// - TBD for kindFunction and kindGenericFunction.
+ dynamic _rest;
+
+ JSArray get interfaceTypeArguments {
+ // The array is a plain JavaScript Array, otherwise we would need the type
+ // `JSArray<Rti>` to exist before we could create the type `JSArray<Rti>`.
+ assert(_kind == kindInterface);
+ return JS('JSUnmodifiableArray', '#', _primary);
+ }
+
+ /// On [Rti]s that are type environments, derived types are cached on the
+ /// environment to ensure fast canonicalization. Ground-term types (i.e. not
+ /// dependent on class or function type parameters) are cached in the
+ /// universe. This field starts as `null` and the cache is created on demand.
+ dynamic _evalCache;
+}
+
+Rti _rtiEval(Rti environment, String recipe) {
+ throw UnimplementedError('_rtiEval');
+}
+
+Rti _rtiBind1(Rti environment, Rti type) {
+ throw UnimplementedError('_rtiBind1');
+}
+
+Rti _rtiBind(Rti environment, Rti typeTuple) {
+ throw UnimplementedError('_rtiBind');
+}
+
+Type getRuntimeType(object) {
+ throw UnimplementedError('getRuntimeType');
+}
+
+// Entry points for testing
+
+String testingRtiToString(dynamic rti) {
+ return 'Rti';
+}
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index 58a9e90..f848a09 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -152,6 +152,8 @@
dart2jsPatchPath: "_internal/js_runtime/lib/internal_patch.dart"),
"_js_helper": const LibraryInfo("_internal/js_runtime/lib/js_helper.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
+ "_rti": const LibraryInfo("_internal/js_runtime/lib/rti.dart",
+ categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_interceptors": const LibraryInfo(
"_internal/js_runtime/lib/interceptors.dart",
categories: "",
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 41a30a2..4a0f788 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -265,6 +265,9 @@
"web_sql": {
"uri": "web_sql/dart2js/web_sql_dart2js.dart"
},
+ "_rti": {
+ "uri": "_internal/js_runtime/lib/rti.dart"
+ },
"svg": {
"uri": "svg/dart2js/svg_dart2js.dart"
}
@@ -464,6 +467,9 @@
"_js_helper": {
"uri": "_internal/js_runtime/lib/js_helper.dart"
},
+ "_rti": {
+ "uri": "_internal/js_runtime/lib/rti.dart"
+ },
"js": {
"uri": "js/dart2js/js_dart2js.dart"
}
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index ccd601d..7a5520c 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -245,6 +245,9 @@
_js_helper:
uri: "_internal/js_runtime/lib/js_helper.dart"
+ _rti:
+ uri: "_internal/js_runtime/lib/rti.dart"
+
_interceptors:
uri: "_internal/js_runtime/lib/interceptors.dart"
@@ -334,6 +337,9 @@
_js_helper:
uri: "_internal/js_runtime/lib/js_helper.dart"
+ _rti:
+ uri: "_internal/js_runtime/lib/rti.dart"
+
_interceptors:
uri: "_internal/js_runtime/lib/interceptors.dart"
@@ -351,6 +357,7 @@
_async_await_error_codes:
uri: "_internal/js_runtime/lib/shared/async_await_error_codes.dart"
+
dartdevc:
libraries:
_runtime:
diff --git a/tests/compiler/dart2js_extra/rti/simple_test.dart b/tests/compiler/dart2js_extra/rti/simple_test.dart
new file mode 100644
index 0000000..636a457
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/simple_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+main() {
+ Expect.equals('Rti', rti.testingRtiToString(null));
+}